home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / Em / locate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-17  |  124.6 KB  |  4,126 lines

  1.  
  2. /*
  3.  * %W%  %G%
  4.  */
  5.  
  6. /* Copyright 1986 Eric Jul and Norm Hutchinson
  7.  * Modifications Copyright 1988,1989 Clinton Jeffery
  8.  * May not be used for any purpose without written permission from the authors.
  9.  * The Emerald kernel for the Emerald programming language.
  10.  * Version 5.4 started 1986-06-16, eric
  11.  * Version 6.0 started 1988-07-21 cjeffery @(#)locate.c    1.7 4/5/89
  12.  */
  13.  
  14. #include <stdio.h>
  15.  
  16. #include "Kernel/h/system.h"
  17. #include "Kernel/h/assert.h"
  18. #include "Kernel/h/macros.h"
  19. #include "Kernel/h/errMsgs.h"
  20. #include "Kernel/h/mmCodes.h"
  21. #include "Kernel/h/emTypes.h"
  22. #include "Kernel/h/timerTypes.h"
  23. #include "Kernel/h/kmdTypes.h"
  24. #include "Kernel/h/kEvents.h"
  25. #include "Kernel/h/emCodes.h"
  26. #include "Kernel/h/mmMsgTypes.h"
  27. #include "Kernel/h/lmTypes.h"
  28. #include "Kernel/h/emkDefs.h"
  29. #include "Kernel/h/lmCodes.h"
  30. #include "Kernel/h/hotsTypes.h"
  31. #include "Kernel/h/map.h"
  32. #include "Kernel/h/set.h"
  33. #include "Kernel/h/expandArray.h"
  34. #include "Kernel/h/consts.h"
  35. #include "Kernel/h/utils.h"
  36. #include "Kernel/h/cPLog.h"
  37. #include "Kernel/h/cPDBM.h"
  38. #include "Kernel/h/checkPoint.h"
  39. #include "Kernel/h/replicant.h"
  40. extern void unavail();
  41.  
  42.  
  43. /*
  44.  * CHECKPOINT support is now integrated into this module-- 7/22/88 cjeffery
  45.  *
  46.  * Throughout the move _delivery_ subsystem, a null LMHandle
  47.  * signifies a Checkpoint operation instead of the usual move.
  48.  * The recovery subsystem typically uses LMHandles as replicantPtrs.
  49.  */
  50. #define ISCHECKPOINT (!fHandlePtr)
  51. #ifdef CHECKPOINT
  52.  
  53. #define GETDATA(hp,off,lena)\
  54.   if(isRecovery){\
  55.     CP_GetData(((replicantPtr)(hp)),(off),(lena));\
  56.   } else {\
  57.     LMGetData((hp),(off),(lena));\
  58.   }
  59. #define PUTDATA(hp,addr,len){\
  60.   if(ISCHECKPOINT) CP_PutData((addr),(len));\
  61.   else LMPutData((hp),(addr),(len));}
  62. #define SEEKDATA(hp, val, from)\
  63.   if(isRecovery){\
  64.     (void)CP_Seek((hp), (val), (from));\
  65.   } else {\
  66.     LMSeek((hp), (val), (from));\
  67.   }
  68.  
  69. #else CHECKPOINT
  70.  
  71. #define GETDATA(hp, off, lena) LMGetData((hp),(off),(lena))
  72. #define PUTDATA(hp,addr,len) LMPutData((hp),(addr),(len))
  73. #define SEEKDATA(hp, val, from) LMSeek((hp),(val),(from))
  74.  
  75. #endif CHECKPOINT
  76.  
  77.  
  78.  
  79. extern EmLocation           thisNodeLocation;
  80. extern SSPtr                removeQ(), readyQ, preemptRunning();
  81. extern void                 schedule(), fail();
  82. extern void                 insertQ();
  83. extern ODTag                stdCodeODTag, stdGODTag;
  84. extern GODP                 thisNodeODP;
  85. extern GODP                 GetNodeODPFromLocation();
  86. extern AbConPtr             GetAbCon(), OIDOIDOIDToAbCon();
  87. extern Offset               IPMapLookup();
  88. extern HResult              CheatingCrankupHandler(), StartCheatingCrankup();
  89. extern Boolean              SSValidAddr();
  90. extern Boolean              CheckOnDisk();
  91. extern Boolean              IsNode();
  92. extern Boolean              LoadRequest();
  93. extern OID             getNextOID();
  94. extern SSAddr               SSHighAddr();
  95. extern SSPtr                NewStackSegment();
  96.  
  97. extern void /* Snapshot */  ps();
  98. extern void                 EmallocForEach();
  99. extern void                 MoveARs(), TraverseAndMoveARList(),
  100.                             TranslateVar(), TraverseAndMove(),
  101.                 MoveSSODToTTable();
  102. extern int                  ReturnOffStack;  /* Label in assembly code (!) */
  103.  
  104. /* counters from measure.c */
  105. extern int            cLOC_LocatesDone;
  106. extern int            cLOC_ShoutsSent, cLOC_ShoutBroadcastsSent;
  107. extern int            cLOC_SearchsSent, cLOC_SearchBroadcastsSent;
  108. extern int            cLOC_SearchProdsSent;
  109.  
  110. /* Forward */
  111. void
  112.   OTDump(), OTDataDump(), LOCLocateMap(); /*snapshots*/
  113.  
  114. HResult
  115.   ShoutTimeOut(), SearchTimeOut();
  116. void
  117.   StartShouting(), StartSearching(), EnsureLocationDeamon();
  118.  
  119. /*
  120.  *  Declarations for AddToTTable
  121.  *      Preinitialized structures.
  122.  *      (Saves having to allocate data areas and fill in headers.)
  123.  */
  124.  
  125. TTGODEntry              godEntry;
  126. TTCondEntry             condEntry;
  127. TTSSODEntry             ssodEntry;
  128. TTAbConEntry            abconEntry;
  129. TTCEntry                codeodEntry;
  130. TTLOEntry               loEntry;
  131. TTMoveGODEntry          movegodEntry;
  132. TTMoveCEntry            movecodeodEntry;
  133. TTFetchGODEntry         fetchgodEntry;
  134. TTCodeAddrEntry         codeaddrEntry;
  135. TTMoveCondEntry         moveCondEntry;
  136.  
  137. /*
  138.     The object table, OT, is a dynamically allocated hash table subject
  139.     to rehashing when it gets too full.
  140.     For starters, linear search will be used.
  141. */
  142. #define INITIALOTSIZE    4096
  143. #define INITIALOTMASK    4095
  144. ODP               *OT;
  145. int            OTSize;        /* Size of OT; must be 2**n */
  146. int            OTMask;        /* must be OTSize - 1 */
  147. int            OTLimit;    /* Maximum fill before rehashing */
  148. int            nOT;        /* Current entry count in OT */
  149.  
  150.  
  151. /*
  152.  * Locate and search data structures.
  153.  */
  154. DynArray                shoutList;
  155.  
  156. DynArray                searchList;
  157.  
  158. Map                     LocateMap;
  159.  
  160. /* Kernel return-address table */
  161. Map                     KernelReturnAddressMap, KernelReturnOpNumberMap;
  162.  
  163. /* Auxilliary variables */
  164. LocateInfo             *list;
  165. int                     listlength;
  166.  
  167. Boolean                 LocationDeamonRunning = FALSE;
  168. #define                 LOCDEAMONINTERVAL    10000 /* microseconds */
  169. int                     vLOCDeamonInterval = LOCDEAMONINTERVAL;
  170. #define                 LOCSHOUTINTERVAL   4000000 /* microseconds */
  171. int                     vLOCShoutInterval  = LOCSHOUTINTERVAL;
  172. #define                 LOCSEARCHINTERVAL  6000000 /* microseconds */
  173. int                     vLOCSearchInterval = LOCSEARCHINTERVAL;
  174.  
  175.  
  176. /************************************************************************/
  177.  
  178. typedef struct TRec {
  179.     OID                 theOID;
  180.     Offset              theOffset;
  181. } TRec, *TRecPtr;
  182.  
  183. /************************************************************************/
  184. /*      Object table                                                    */
  185. /************************************************************************/
  186.  
  187. /* Forward */
  188. void                    OTInsert(), MoveToTTable(), AddToTTable();
  189. void                    EmDataDump();
  190. void                    EmCTRefDump();
  191.  
  192. #define OThash(key) ((((key) << 1) ^ ((key) >> 24)) & OTMask)
  193.  
  194. /************************************************************************/
  195. /*      OTRehash                                                        */
  196. /************************************************************************/
  197.  
  198. void OTRehash()
  199. /* This procedure doubles the size of the OT and rehashes it */
  200. {
  201.     register ODP       *stopAtEntry, *entry;
  202.     ODP                *theNewArray, *oldOT;
  203.     time_t              theTime = time((time_t *) 0);
  204.  
  205.     KMDTrace("OT", 2, "Rehashing Object Table, %d entries\n", nOT);
  206.  
  207.     CreateArray((int **)&theNewArray, OTSize*2*sizeof(ODP));
  208.     stopAtEntry = &theNewArray[OTSize*2];
  209.     for (entry = &theNewArray[0]; entry != stopAtEntry; entry++) {
  210.     *entry = (ODP) NULL;
  211.     }
  212.     /* Switch tables and rehash */
  213.     stopAtEntry             = &OT[OTSize];
  214.     OTSize                  += OTSize;
  215.     OTMask                  = OTSize - 1;
  216.     /* Fill no more than 87.5% */
  217.     OTLimit                 = OTSize - (OTSize >> 3) - 1;
  218.     oldOT                   = OT;
  219.     nOT                     = 0;
  220.     OT                      = theNewArray;
  221.     for (entry = &oldOT[0]; entry !=stopAtEntry; entry++) {
  222.     if (NonNULL((*entry))) OTInsert(*entry);
  223.     }
  224.     DiscardArray((int **)&oldOT);
  225.     /* Now log a message */
  226.     ErrMsg("%s: Doubled size of OT to %d entries, now %5.2f percent full.\n",
  227.     ctime(&theTime), OTSize, 100.0 * ((float) nOT) / ((float) OTSize));
  228. }
  229.  
  230. /**********************************************************************/
  231. /*      OTLookup                                                      */
  232. /**********************************************************************/
  233.  
  234. ODP OTLookup(fOID)
  235. OID          fOID;
  236. /* Lookup the given OID in the symbol table and return the
  237.    corresponding ODP, NULL if not found. */
  238. {
  239.     register ODP            *p, *tableEnd;
  240.  
  241.     assert(NonNULL(fOID));
  242.  
  243.     tableEnd = &OT[OTSize];
  244.     p = &OT[OThash(fOID)];
  245.     while (NonNULL(*p)) {
  246.     if (p >= tableEnd) {
  247.          p = & OT[0];
  248.     }
  249.     if ((*p)->G.ownOID == fOID) {
  250.         KMDTrace("OT", 3, "OTLookup(0x%05x) returning 0x%05x\n", fOID,
  251.         *p);
  252.         return(*p);
  253.     }
  254.     p++;
  255.     };
  256.     /* Not found. */
  257.     KMDTrace("OT", 3, "OTLookup(0x%05x) returning NULL\n", fOID);
  258.     return( (ODP) NULL);
  259. }
  260.  
  261. /**********************************************************************/
  262. /*      OTInsert                                                      */
  263. /**********************************************************************/
  264.  
  265. void OTInsert(x)
  266. register ODP            x;
  267. /* Insert x into the object table */
  268. {
  269.     /* Use linear search */
  270.     register int        hashIndex;
  271.  
  272.     if (nOT++ > OTLimit) {
  273.     /* Rehash necessary */
  274.     OTRehash();
  275.     };
  276.  
  277.     if (IsNULL(x->G.ownOID)) {
  278.     x->G.ownOID = getNextOID();
  279.     }
  280.  
  281.     hashIndex = OThash(x->G.ownOID);    
  282.     /* Find empty entry */
  283.     for (;OT[hashIndex]!=(ODP)NULL && OT[hashIndex]->G.ownOID != x->G.ownOID;)
  284.     if (++hashIndex >= OTSize) hashIndex=0;
  285.     if (NonNULL(OT[hashIndex]))
  286.     KMDTrace("OT", 2, "OTInsert duplicate OID 0x%05x\n", x->G.ownOID);
  287.     OT[hashIndex] = x;
  288.     KMDTrace("OT", 3, "OTInsert[%d]:: OID 0x%05x\n", hashIndex,
  289.     x->G.ownOID);    
  290. }
  291.  
  292.  
  293. /**********************************************************************/
  294. /*      OTForEach                                                      */
  295. /**********************************************************************/
  296.  
  297. void OTForEach(f)
  298. int (*f)();
  299. /* Call f for with the address of each entry in the object table */
  300. {
  301.   register int        hashIndex;
  302.  
  303.   for (hashIndex = 0; hashIndex < OTSize; hashIndex++) {
  304.     if (OT[hashIndex] != (ODP)NULL) {
  305.       f(&OT[hashIndex]);
  306.     }
  307.   }
  308. }
  309.  
  310. /*
  311.  * For each object table entry that is -1, re-insert all following ones.
  312.  */
  313. void OTFinishDelete()
  314. {
  315.   register ODP *p, x, *tableEnd;
  316.   register int done = 0;
  317.  
  318.   for (p = &OT[0], tableEnd = &OT[OTSize]; p < tableEnd && !done; p++) {
  319.     if (*p == (ODP) -1) {
  320.       *p = NULL;
  321.       KMDTrace("OT", 3, "OTDelete[%d]\n", p-&OT[0]);
  322.       if (++p >= tableEnd) { p = &OT[0]; done = 1; }
  323.       while (NonNULL(*p)) {
  324.     x = *p;
  325.     *p = NULL;
  326.     if (x != (ODP)-1) OTInsert(x);
  327.     p++;
  328.     if (p >= tableEnd) { p = &OT[0]; done = 1; }
  329.       }
  330.     }
  331.   }
  332. }
  333.  
  334. /*
  335.  * getFreeOD
  336.  *
  337.  * Gets a free entry in the object table
  338.  */
  339. ODP getFreeOD()
  340. {
  341.   return ( (ODP) emallocnil(sizeof(OD)) );
  342. }
  343.  
  344.  
  345.  
  346. /*
  347.  * CreateUnknownGODEntry
  348.  */
  349. GODP CreateUnknownGODEntry(fOID)
  350. OID         fOID;
  351. {
  352.   GODP    p       = (GODP) getFreeOD();
  353.   
  354.   p->ownOID       = fOID;
  355.   p->ownLoc       = (EmLocation) NULL;
  356.   p->tag          = stdGODTag;
  357.   p->tag.frozen   = TRUE;
  358.   p->tag.isResident = FALSE;
  359.   p->dataPtr      = (GODataPtr) NULL;
  360.   OTInsert((ODP) p);
  361.   return p;
  362. }
  363.  
  364.  
  365.  
  366. /*
  367.  * CreateGODEntry
  368.  */
  369. GODP CreateGODEntry(fOID, fCodeOID)
  370. OID         fOID, fCodeOID;
  371. {
  372.   GODP    p       = (GODP) getFreeOD();
  373.   KMDTrace("TT", 3, "CreateGODEntry(0x%05x, 0x%05x)\n", fOID, fCodeOID);
  374.   p->ownOID       = fOID;
  375.   p->ownLoc       = (EmLocation) NULL;
  376.   p->tag          = stdGODTag;
  377.   p->tag.frozen   = TRUE;
  378.   p->tag.isResident = FALSE;
  379.   p->dataPtr      = (GODataPtr) NULL;
  380.   p->myCodeOID    = fCodeOID;
  381.   p->ARListHead.next = p->ARListHead.prev = (InvokeQueuePtr) &p->ARListHead;
  382.   OTInsert((ODP) p);
  383.   return p;
  384. }
  385.  
  386.  
  387.  
  388. /*
  389.  * CreateCodeODEntry
  390.  *
  391.  * If necessary, create an OD for remote code
  392.  */
  393. CodeODP CreateCodeODEntry(fCodeOID, fLocation)
  394. OID         fCodeOID;
  395. EmLocation  fLocation;
  396. {
  397.   register CodeODP p;
  398.  
  399.   if (NonNULL(p = (CodeODP) OTLookup(fCodeOID))) {    /* We already know it */
  400.     return p;
  401.   }
  402.   KMDTrace("Code",3, "CreateCodeODEntry(0x%05x, 0x%05x)\n",fCodeOID,fLocation);
  403.  
  404.   p                 = (CodeODP) emalloc(sizeof(CodeOD));
  405.   p->ownOID         = fCodeOID;
  406.   p->ownLoc         = fLocation;
  407.   p->tag            = stdCodeODTag;
  408.   p->tag.frozen     = TRUE;
  409.   p->tag.isResident = FALSE;
  410.   p->tag.setUpDone  = FALSE;
  411.   p->dataPtr        = (CodePtr) NULL;
  412.   p->AbConSetPtr    = (GenericPtr) Set_Create();
  413.   p->depCode        = (GenericPtr) NULL;
  414.   OTInsert((ODP) p);
  415.   return p;
  416. }
  417.  
  418. /************************************************************************/
  419. /************************************************************************/
  420. /*          Location algorithm                                          */
  421. /************************************************************************/
  422. /************************************************************************/
  423.  
  424. /************************************************************************/
  425.  
  426. void RemoveFromSearchLists(fReq)
  427. LocateReqPtr fReq;
  428. {
  429.   register int  i, count;
  430.   register OID *p;
  431.  
  432.   KMDTrace("Locate", 3, "Remove from search lists\n");
  433.  
  434.   if (fReq->status == Shouting) {    /* Remove from Shout list */
  435.     count = DynCount(shoutList);
  436.     p = (OID *) &shoutList->array[count-1];
  437.     for (i = count - 1; i >= 0; i--, p--) {
  438.       if (*p == fReq->theOID) DynRemove(shoutList, i);
  439.     }
  440.   }
  441.   if (fReq->status == Searching) {    /* Remove from search list */
  442.     count = DynCount(searchList);
  443.     p = (OID *) &searchList->array[count-1];
  444.     for (i = count - 1; i >= 0; i--, p--) {
  445.       if (*p == fReq->theOID) DynRemove(searchList, i);
  446.     }
  447.   }
  448. }
  449. /************************************************************************/
  450. /* call back */
  451. HResult FoundIt(fReq, fOID)
  452. register LocateReqPtr fReq;
  453. register OID          fOID;
  454. {
  455.   register ODP theODP = (ODP) OTLookup(fOID);
  456.   assert(NonNULL(theODP));
  457.   KMDTrace("Locate", 3, "%s found at 0x%04x\n", PPOID(fOID), theODP->G.ownLoc);
  458.   if (fReq->status == Shouting || fReq->status == Searching) {
  459.     RemoveFromSearchLists(fReq);
  460.   }
  461.   Map_Delete(LocateMap, (int) fOID);
  462.   if (fReq->waiting) {
  463.     fReq->waiting->resultBrand = ODPBrand;
  464.     fReq->waiting->regs.arg1 =
  465.       (int) GetNodeODPFromLocation(theODP->G.ownLoc);
  466.     schedule(fReq->waiting);
  467.     fReq->waiting = (SSPtr) NULL;
  468.   }
  469.   DoCallBack((GenericReqPtr) fReq, fOID);
  470.   FreeRequest((GenericReqPtr) fReq);
  471. }
  472.  
  473.  
  474.  
  475. /*
  476.  * CouldNotFindIt
  477.  *
  478.  * The location algorithm has given up.  Report back
  479.  */
  480. void CouldNotFindIt(fReq)
  481. register LocateReqPtr fReq;
  482. {
  483.   register ODP theODP = (ODP) OTLookup(fReq->theOID);
  484.   extern HResult RecoverItemHandler();
  485.   assert(NonNULL(theODP));
  486.   KMDTrace("Locate", 3, "%s not found: 0x%04x\n", PPOID(fReq->theOID),
  487.        theODP->G.ownLoc);
  488.  
  489. #ifdef CHECKPOINT
  490.   /* Inserted logic to recover using a local replicant here */
  491.   if(theODP->G.tag.tag == GODTag && theODP->G.Replicant != (char *)EMNIL) {
  492.     KMDTrace("Recover",3,"%s not found, but we have a replicant at 0x%04x\n",
  493.          PPOID(fReq->theOID),theODP->G.ownLoc);
  494.     RecoverItemHandler(((replicantPtr)(theODP->G.Replicant)),theODP);
  495.     FoundIt(fReq, fReq->theOID);
  496.     return;
  497.   }
  498. #endif
  499.  
  500.   if (fReq->status == Shouting || fReq->status == Searching) {
  501.     RemoveFromSearchLists(fReq);
  502.   }
  503.   Map_Delete(LocateMap, (int) fReq->theOID);
  504.   theODP->G.ownLoc                = (EmLocation) NULL;
  505.   if (NonNULL(fReq->waiting)) {
  506.     fReq->waiting->resultBrand  = VariableBrand;
  507.     fReq->waiting->regs.arg1    = (int) EMNIL;
  508.     fReq->waiting->regs.arg2    = (int) EMNIL;
  509.     schedule(fReq->waiting);
  510.     fReq->waiting               = (SSPtr) NULL;
  511.   }
  512.   DoCallBack((GenericReqPtr) fReq, fReq->theOID);
  513.   FreeRequest((GenericReqPtr) fReq);
  514. }
  515.  
  516.  
  517.  
  518. /*
  519.  * StartConfirming
  520.  */
  521. void StartConfirming(fReq)
  522. register LocateReqPtr fReq;
  523. {
  524.   LocateItem    l;
  525.   LMHandle      myHandle;
  526.   HOTSRecordPtr HOTS;
  527.   NodeNum       lnn;
  528.  
  529.   lnn = mGetLocNodeNum(fReq->theLocation);
  530.   if (IsNULL(lnn) || !mSUCCESS(HOTSSearchPtr(lnn, &HOTS)) ||
  531.       HOTS->NodeStat != Alive) {
  532.     /* The node is not considered alive, move along to shouting */
  533.     KMDTrace("Locate", 3, "0x%08x on unknown or down node %d\n",
  534.          fReq->theOID, lnn);
  535.     StartShouting(fReq);
  536.     return;
  537.   }
  538.   fReq->status = Confirming;
  539.   KMDTrace("Locate", 3, "Start confirmation for 0x%05x @ 0x%05x\n",
  540.        fReq->theOID, fReq->theLocation);
  541.  
  542.   l.hdr.itemTag       = ConfirmITag;
  543.   l.hdr.size          = sizeof(l);
  544.   l.obj[0].theOID     = fReq->theOID;
  545.   l.obj[0].theLocation= fReq->theLocation;
  546.   LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, lnn);
  547.   LMPutData(&myHandle, &l, sizeof(l));
  548.   LMSendMsg(&myHandle);
  549. }
  550.  
  551.  
  552.  
  553. /*
  554.  * StartShouting
  555.  */
  556. void StartShouting(fReq)
  557. register LocateReqPtr fReq;
  558. {
  559.   Boolean result;
  560.     
  561.   KMDTrace("Locate", 3, "StartShouting for OID 0x%05x\n", fReq->theOID);
  562.   if ((((unsigned int) fReq->theOID >> 24) & 0xFF) == 0xFF) {
  563.     /* Check on own disk first */
  564.     if (CheckOnDisk(fReq->theOID)) {
  565.       KMDTrace("Locate", 3, "Found %s on disk.\n", PPOID(fReq->theOID));
  566.       fReq->status            = WaitingForCodeLoad;
  567.       fReq->hdr.callBack      = (GenericHandlerPtr) FoundIt;
  568.       result = LoadRequest(fReq->theOID, (GenericReqPtr) fReq);
  569.       if (result && NonNULL(OTLookup(fReq->theOID))) {
  570.     KMDTrace("Locate", 4, "Got %s loaded.\n", PPCOID(fReq->theOID));
  571.     /* Now do the up call */
  572.     FoundIt(fReq, fReq->theOID);
  573.     return;
  574.       }
  575.       if (NonNULL(OTLookup(fReq->theOID))) {
  576.     KMDTrace("FixMe", 3, "obj was compiler created ???\n");
  577.     KMDTrace("Locate", 4, "Did not get it all loaded; waiting\n");
  578.     return;
  579.       }
  580.     }
  581.     KMDTrace("Locate", 4, "Did not find it on disk; now shouting.\n");
  582.   }
  583.  
  584.   fReq->status            = Shouting;
  585.   /* Enter into shoutList */
  586.   DynAddUpper(shoutList, (int) fReq->theOID);
  587.   EnsureLocationDeamon();
  588.   (void) MMSetMicroTimer((int)(vLOCShoutInterval/1000000),
  589.       (int)(vLOCShoutInterval%1000000), (HandlerPtr)ShoutTimeOut,
  590.       (int)fReq->theOID, (TimerId *)&fReq->timerId);
  591. }
  592.  
  593.  
  594.  
  595. /*
  596.  * StartSearching
  597.  */
  598. void StartSearching(fReq)
  599. LocateReqPtr fReq;
  600. {
  601.   register unsigned char *first;
  602.   register LocateReqPtr   req = fReq;
  603.   register GODP           theObj;
  604.   extern HResult StartCheatingCrankup();
  605.  
  606.   req->status            = Searching;
  607.   first = &req->replyList[0];
  608.   bzero((char *)first,&req->replyList[MAXNODENUMBER]-first);
  609.  
  610.   KMDTrace("Locate", 3, "Start Searching for OID 0x%05x\n", req->theOID);
  611.   if ((req->theOID >> 24 & 0xFF) == 0xFE) {
  612.     /* It was created by the compiler so look on disk */
  613.     KMDTrace("Locate", 4, "Trying on disk\n");
  614.     if (CheckOnDisk(req->theOID)) {
  615.       KMDTrace("Locate", 3, "Found on disk, crank it up\n");
  616.       /* Create a GOD entry for it */
  617.       if (IsNULL(OTLookup(req->theOID))) {
  618.     theObj = CreateGODEntry(req->theOID, (OID) NULL);
  619.     theObj->ownLoc = thisNodeLocation;
  620.     theObj->tag.isResident = TRUE;
  621.     theObj->tag.setUpDone = FALSE;
  622.     KMDTrace("Create", 3, "GOD for Cheating object %s\n",
  623.          PPGOID(req->theOID));
  624.       }
  625.       req->status    = WaitingForCodeLoad;
  626.       StartCheatingCrankup(req->theOID, (GenericReqPtr) req);
  627.       return;
  628.     }
  629.   }
  630.  
  631.   /* Enter into search list */
  632.   DynAddUpper(searchList, (int) fReq->theOID);
  633.   EnsureLocationDeamon();
  634.   (void)MMSetMicroTimer((int)(vLOCSearchInterval/1000000),
  635.     (int)(vLOCSearchInterval%1000000), (HandlerPtr)SearchTimeOut,
  636.     (int)fReq->theOID, (TimerId *)&fReq->timerId);
  637. }
  638.  
  639.  
  640.  
  641.  
  642. /*
  643.  * RedoConfirm
  644.  */
  645. void RedoConfirm(fReq)
  646. LocateReqPtr fReq;
  647. {
  648.   KMDTrace("Locate", 3, "RedoConfirm for OID 0x%05x\n", fReq->theOID);
  649.   StartConfirming(fReq);
  650. }
  651.  
  652.  
  653.  
  654. /*
  655.  *  SendLocationProd
  656.  */
  657. void SendLocationProd(fLNN, fOID)
  658. NodeNum fLNN;
  659. OID fOID;
  660. {
  661.   LMHandle myHandle;
  662.   LocateItem item;
  663.  
  664.   KMDTrace("Locate", 3, "Sending prod for %s to node #%d\n", PPOID(fOID),fLNN);
  665.   LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, fLNN);
  666.   item.hdr.itemTag        = SearchITag;
  667.   item.hdr.size           = sizeof(item);
  668.   item.obj[0].theOID      = fOID;
  669.   item.obj[0].theLocation = (EmLocation) NULL;
  670.   LMPutData(&myHandle, &item, sizeof(item));
  671.   cLOC_SearchProdsSent++;
  672.   (void) LMSendMsg(&myHandle);
  673. }
  674.  
  675.  
  676.  
  677. void GoThroughReplyListToSeeIfEveryoneHasReplied(fReq, sendProd)
  678. LocateReqPtr fReq;
  679. Boolean sendProd;
  680. {
  681.   register int i;
  682.   register struct HOTStr *np;
  683.   int prodCount;
  684.   KMDTrace("Locate", 4, "Checking for search completion for %s\n",
  685.        PPOID(fReq->theOID));
  686.   /* Traverse HOTS table and create list of entries */
  687.   prodCount = 0;
  688.   for (i=0; i < HOTSIZE; i++) {
  689.     for(np = HOTSTable[i]; np != NULL; np = np -> next) {
  690.       if (np->ThisEntry.NodeStat == Alive &&
  691.       (np->ThisEntry.LNN != GetLNN()) &&
  692.       ! (Boolean) fReq->replyList[np->ThisEntry.LNN]) {
  693.     if(sendProd)SendLocationProd(np->ThisEntry.LNN, fReq->theOID);
  694.     prodCount++;
  695.       }
  696.     }
  697.   }
  698.   if(sendProd)KMDTrace("Locate", 3, "Prodded %d nodes.\n", prodCount);
  699.   if (prodCount == 0) {
  700.     KMDTrace("Locate", 3, "Search result: Cannot find object %s\n",
  701.          PPOID(fReq->theOID));
  702.     CouldNotFindIt(fReq);
  703.   } else {
  704.     KMDTrace("Locate", 4, "Search not done yet.\n");
  705.     if(sendProd)KMDTrace("Locate", 4, "  (prodded %d nodes)\n",prodCount);
  706.   }
  707. }
  708.  
  709.  
  710. void CheckForSearchDone(fReq)
  711. LocateReqPtr fReq;
  712. {
  713.   GoThroughReplyListToSeeIfEveryoneHasReplied(fReq, False);
  714. }
  715.  
  716.  
  717.  
  718. void CheckForProd(fReq)
  719. LocateReqPtr fReq;
  720. {
  721.   GoThroughReplyListToSeeIfEveryoneHasReplied(fReq, True);
  722. }
  723.  
  724. /************************************************************************/
  725. /************************************************************************/
  726.  
  727. /************************************************************************/
  728. /*      NewLocation                                                     */
  729. /************************************************************************/
  730. EmLocation NewLocation(fOldLocation, fNewLNN)
  731. EmLocation          fOldLocation;
  732. NodeNum             fNewLNN;
  733. {
  734.     return mMakeLocation(fNewLNN, mGetLocTimeStamp(fOldLocation)+1);
  735. }
  736.  
  737.  
  738.  
  739.  
  740. /*
  741.  * UpdateLocation
  742.  *
  743.  * Update the OT with new location information
  744.  */
  745. void UpdateLocation(fOID, fNewLocation, fInfoSrc)
  746. OID        fOID;
  747. EmLocation fNewLocation;
  748. NodeNum    fInfoSrc;
  749. {
  750.   register ODP            theODP;
  751.   register LocateReqPtr   req;
  752.   EmLocation              oldLocation;
  753.   NodeNum                 nodeLNN;
  754.   Boolean                 gotNewLoc;
  755.     
  756.   theODP = OTLookup(fOID);
  757.   if (IsNULL(theODP)) {
  758.     KMDTrace("Locate", 2, "Unknown object (0x%04x) -- ignored\n",fOID);
  759.     return;
  760.   }
  761.  
  762.   /* Check to see if location timestamp is newer */
  763.   oldLocation = theODP->G.ownLoc;
  764.   gotNewLoc= mGetLocTimeStamp(oldLocation) < mGetLocTimeStamp(fNewLocation);
  765.  
  766.   if (gotNewLoc) {
  767.     KMDTrace("Locate", 3,
  768.          "OID 0x%05x was @ 0x%04x now @ 0x%04x; source: node #%d\n",
  769.          theODP->G.ownOID, theODP->G.ownLoc, fNewLocation, fInfoSrc);
  770.     theODP->G.ownLoc = fNewLocation;
  771.     KMDTrace("FixMe", 3, "Fix me: should reset ODTag flags.\n");
  772.   }
  773.  
  774.   /* Check outstanding requests */
  775.  
  776.   req = (LocateReqPtr) Map_Lookup(LocateMap, (int) fOID);
  777.   if (IsNIL(req)) return;
  778.  
  779.   nodeLNN = mGetLocNodeNum(fNewLocation);
  780.   req->replyList[fInfoSrc] = (unsigned char) TRUE;
  781.   if (gotNewLoc) {
  782.     req->theLocation = fNewLocation;
  783.   }
  784.     
  785.   /* We have found a request for the object */
  786.   switch (req->status) {
  787.  
  788.   case Waiting:
  789.   case WaitingForCodeLoad:
  790.     /* ignore */
  791.     break;
  792.  
  793.   case Confirming:
  794.     if (mGetLocNodeNum(oldLocation) == fInfoSrc) {
  795.       /* It is the guy we were requesting a confirmation from */
  796.  
  797.       if (nodeLNN == fInfoSrc) {
  798.       HEHASIT:
  799.     KMDTrace("Locate",3, "OID 0x%05x found @ 0x%05x\n", fOID,fNewLocation);
  800.     FoundIt(req, fOID);
  801.       } else        /* He is giving us a new location */
  802.     if (gotNewLoc) {
  803.     REDO:
  804.       KMDTrace("Locate", 3, "Redoing confirm\n");
  805.       RedoConfirm(req);
  806.     } else {
  807.       KMDTrace("Locate", 3, "OID 0x%05x negative confirmation from %d\n",
  808.            fOID, fInfoSrc);
  809.       StartShouting(req);
  810.     }
  811.       return;
  812.     }
  813.     if (gotNewLoc) RedoConfirm(req);
  814.     return;
  815.  
  816.   case Shouting:
  817.     if (gotNewLoc) {
  818.     GOTNEWLOC:
  819.       if (nodeLNN==fInfoSrc) goto HEHASIT;
  820.       else goto REDO;
  821.     }
  822.     return;
  823.  
  824.   case Searching:
  825.     if (gotNewLoc) goto GOTNEWLOC;
  826.     else {
  827.       req->replyList[fInfoSrc] = TRUE;
  828.       CheckForSearchDone(req);
  829.     }
  830.   }
  831. }
  832.  
  833.  
  834.  
  835. /*
  836.  * Callback routine for locate requests
  837.  */
  838. HResult LocatePrevDone(fReq, fOID)
  839. register LocateReqPtr fReq;
  840. OID fOID;
  841. {
  842.   LocateReqPtr oldReq;
  843.   oldReq = (LocateReqPtr) Map_Lookup(LocateMap, (int) fOID);
  844.  
  845.   if (oldReq != (LocateReqPtr) EMNIL) {
  846.     /* A location request already exists */
  847.     Map_Insert(oldReq->hdr.reqBy, (int) fReq, 0);
  848.     Map_Insert(fReq->hdr.wantList, (int) oldReq, 0);
  849.     fReq->hdr.callBack = (GenericHandlerPtr) LocatePrevDone;
  850.     KMDTrace("Locate", 3,
  851.          "Awaiting location of 0x%05x @ 0x%05x; in %s\n", fReq->theOID,
  852.          fReq->theLocation, PPSSPlace(fReq->waiting));
  853.     return;
  854.   }
  855.   Map_Insert(LocateMap, (int) fOID, (int) fReq);
  856.   fReq->hdr.callBack   = (GenericHandlerPtr) NULL;
  857.   KMDTrace("Locate", 3, "Locate reconfirming for 0x%05x @ 0x%02x\n",
  858.        fReq->theOID, fReq->theLocation);
  859.   StartConfirming(fReq);
  860. }
  861.  
  862.  
  863.  
  864. /*
  865.  * Kernel call to locate objects
  866.  */
  867. void Locate(fODP, fAbConPtr)
  868. register ODP      fODP;
  869. register AbConPtr fAbConPtr;
  870. {
  871.   register LocateReqPtr req, oldReq;
  872.  
  873.   if (fAbConPtr == (AbConPtr) EMNIL || fODP == (ODP) EMNIL) {
  874.     KMDTrace("Locate", 3, "Location of NIL causes failure\n");
  875.     KMDTrace("Failure", 3, "locate of NIL causes failure\n");
  876.     fail(preemptRunning());
  877.   } else if (fAbConPtr->tag.allInstancesAreLocal) {
  878.     KMDTrace("Locate", 3, "Location of local object returns own node.\n");
  879.     currentSSP->resultBrand = ODPBrand;
  880.     currentSSP->regs.arg1 = (int) thisNodeODP;
  881.   } else if (((fODP->G.tag.tag == GODTag) && !fODP->G.tag.global)
  882.          || (fODP->G.tag.isResident)) {
  883.     KMDTrace("Locate", 3, "Location of resident object returns own node.\n");
  884.     currentSSP->resultBrand = ODPBrand;
  885.     currentSSP->regs.arg1 = (int) thisNodeODP;
  886.   } else if (IsNode(fODP)) {
  887.     KMDTrace("Locate", 3, "Location of node returns the node.\n");
  888.     currentSSP->resultBrand = ODPBrand;
  889.     currentSSP->regs.arg1 = (int) fODP;
  890.   } else {
  891.     /* It is a non-resident object; crank up location protocol */
  892.     cLOC_LocatesDone++;
  893.     req = mNewRequest(Locate);
  894.     currentSSP->invokePtr = (GenericPtr) req;
  895.     req->status           = Confirming;
  896.     req->theOID           = fODP->G.ownOID;
  897.     req->theLocation      = fODP->G.ownLoc;
  898.     oldReq = (LocateReqPtr) Map_Lookup(LocateMap, (int) fODP->G.ownOID);
  899.     if (oldReq != (LocateReqPtr) EMNIL) {
  900.       /* A location request already exists */
  901.       Map_Insert(oldReq->hdr.reqBy, (int) req, 0);
  902.       Map_Insert(req->hdr.wantList, (int) oldReq, 0);
  903.       req->hdr.callBack = (GenericHandlerPtr) LocatePrevDone;
  904.       req->waiting    = preemptRunning();
  905.       req->waiting->status.rs = SSLocateWait;
  906.       KMDTrace("LineNumber", 4, "%s waiting for locate to complete in %s\n",
  907.            PPPOID(req->waiting->processOID), PPSSPlace(req->waiting));
  908.       KMDTrace("Locate", 3,"Awaiting location of 0x%05x @ 0x%05x; in %s\n",
  909.            req->theOID, req->theLocation, PPSSPlace(req->waiting));
  910.       return;
  911.     }
  912.     Map_Insert(LocateMap, (int) req->theOID, (int) req);
  913.     req->hdr.callBack   = (GenericHandlerPtr) FoundIt;
  914.     req->waiting        = preemptRunning();
  915.     req->waiting->status.rs = SSLocateWait;
  916.     KMDTrace("LineNumber", 4, "%s waiting for locate to complete in %s\n",
  917.          PPPOID(req->waiting->processOID), PPSSPlace(req->waiting));
  918.  
  919.     KMDTrace("Locate", 3,
  920.          "Locate startup for 0x%05x @ 0x%05x; in %s\n", req->theOID,
  921.          req->theLocation, PPSSPlace(req->waiting));
  922.     StartConfirming(req);
  923.   }
  924. }
  925.  
  926.  
  927.  
  928. /*
  929.  * StartLocate
  930.  */
  931. void StartLocate(fReq, fODP)
  932. GenericReqPtr fReq;
  933. ODP           fODP;
  934. {
  935.   register LocateReqPtr   req, oldReq;
  936.  
  937.   KMDTrace("Locate", 3, "StartLocate for %s\n", PPOID(fODP->G.ownOID));
  938.   cLOC_LocatesDone++;
  939.  
  940.   req                     = mNewRequest(Locate);
  941.   Map_Insert(fReq->hdr.wantList, (int) req, 0);
  942.   Map_Insert(req->hdr.reqBy, (int) fReq, 0);
  943.   req->status             = Confirming;
  944.   req->theOID             = fODP->G.ownOID;
  945.   req->theLocation        = fODP->G.ownLoc;
  946.   req->waiting            = (SSPtr) NULL;
  947.   oldReq = (LocateReqPtr) Map_Lookup(LocateMap, (int) fODP->G.ownOID);
  948.  
  949.   if (oldReq != (LocateReqPtr) EMNIL) {
  950.     /* A location request already exists */
  951.     Map_Insert(oldReq->hdr.reqBy, (int) req, 0);
  952.     Map_Insert(req->hdr.wantList, (int) oldReq, 0);
  953.     req->hdr.callBack = (GenericHandlerPtr) LocatePrevDone;
  954.     KMDTrace("Locate", 3, "Awaiting location of 0x%05x @ 0x%05x; in %s\n",
  955.          req->theOID, req->theLocation, PPSSPlace(req->waiting));
  956.     return;
  957.   }
  958.   Map_Insert(LocateMap, (int) req->theOID, (int) req);
  959.   req->hdr.callBack   = (GenericHandlerPtr) FoundIt;
  960.  
  961.   KMDTrace("Locate", 3, "Locate startup for 0x%05x @ 0x%02x\n",
  962.        req->theOID, req->theLocation);
  963.   StartConfirming(req);
  964. }
  965.  
  966. /*
  967.  * UnpackLocateItem - returns count of contents
  968.  */
  969. int UnpackLocateItem(fHandlePtr,fHdr)
  970. LMHandlePtr    fHandlePtr;
  971. ItemHdr        fHdr;
  972. {
  973.   register int length = fHdr.size - sizeof(fHdr);
  974.   int size = length;
  975.   while (length > listlength) {
  976.     ExpandArray((int **)&list, listlength, listlength*2);
  977.     listlength += listlength;
  978.   }
  979.   LMGetData(fHandlePtr, list, &size);
  980.   assert(length == size);
  981.   return length / sizeof(LocateInfo);
  982. }
  983.  
  984. /*
  985.  * SendLocateReply
  986.  */
  987. void SendLocateReply(fHandlePtr, fHdr, tag)
  988. LMHandlePtr fHandlePtr;
  989. ItemHdr     fHdr;
  990. ITag tag;
  991. {
  992.   LMHandle replyHandle;
  993.   LMStartMsg(&replyHandle, KMSG_EmKernel, EMKM_Item,
  994.          (*fHandlePtr)->mmMsgHdr.MsgSrc);
  995.   fHdr.itemTag = tag;
  996.   LMPutData(&replyHandle, &fHdr, sizeof(fHdr));
  997.   LMPutData(&replyHandle, list, (int)(fHdr.size - sizeof(fHdr)));
  998.   LMSendMsg(&replyHandle);
  999. }
  1000.  
  1001. /*
  1002.  * ConfirmItemHandler
  1003.  */
  1004. HResult ConfirmItemHandler(fHandlePtr, fHdr)
  1005. LMHandlePtr fHandlePtr;
  1006. ItemHdr     fHdr;
  1007. {
  1008.   int count, i;
  1009.   register ODP theODP;
  1010.  
  1011.   KMDTrace("Locate", 3, "Confirm Item from node %d\n",
  1012.        (*fHandlePtr)->mmMsgHdr.MsgSrc);
  1013.  
  1014.   count = UnpackLocateItem(fHandlePtr, fHdr);
  1015.   for (i = 0; i < count; i++) {
  1016.     KMDTrace("Locate", 4, "Confirm OID 0x%05x @ 0x%05x\n",
  1017.          list[i].theOID, list[i].theLocation);
  1018.     theODP = OTLookup(list[i].theOID);
  1019.     if (IsNULL(theODP)) {
  1020.       KMDTrace("Locate", 4, "Negative confirmation of OID 0x%05x\n",
  1021.            list[i].theOID);
  1022.       list[i].theLocation    = (EmLocation) NULL;
  1023.     } else {
  1024.       KMDTrace("FixMe", 5, "Fix me: need to confirm move\n");
  1025.       KMDTrace("Locate", 4, "Confirm reply for OID 0x%05x: @ 0x%05x\n",
  1026.            theODP->G.ownOID, theODP->G.ownLoc);
  1027.       list[i].theLocation    = theODP->G.ownLoc;    
  1028.     }
  1029.   }
  1030.   SendLocateReply(fHandlePtr, fHdr, ConfirmReplyITag);
  1031. }
  1032.  
  1033.  
  1034.  
  1035. /*
  1036.  * ShoutItemHandler
  1037.  */
  1038. HResult ShoutItemHandler(fHandlePtr, fHdr)
  1039. LMHandlePtr     fHandlePtr;
  1040. ItemHdr         fHdr;
  1041. {
  1042.   int          count, i, j;
  1043.   register ODP theODP;
  1044.     
  1045.   KMDTrace("Locate",3, "Shout item from %d\n", (*fHandlePtr)->mmMsgHdr.MsgSrc);
  1046.  
  1047.   count = UnpackLocateItem(fHandlePtr,fHdr);
  1048.   j = 0; /* Note, the same list is used for replying */
  1049.   for (i = 0; i < count; i++) {
  1050.     KMDTrace("Locate", 4, "Shout was for OID 0x%05x @ 0x%05x\n",
  1051.          list[i].theOID, list[i].theLocation);
  1052.     theODP = OTLookup(list[i].theOID);
  1053.     if (IsNULL(theODP) ||
  1054.     (mGetLocNodeNum(theODP->G.ownLoc) != (unsigned int) GetLNN())) {
  1055.       if ((((unsigned int) list[i].theOID >> 24) & 0xFF) == 0xFF) {
  1056.     /* Check on own disk */
  1057.     if (CheckOnDisk(list[i].theOID)) {
  1058.       KMDTrace("Locate", 3, "Found %s on disk.\n",
  1059.            PPOID(list[i].theOID));
  1060.       list[j].theLocation = thisNodeLocation;
  1061.       list[j].theOID  = list[i].theOID;
  1062.       j++;
  1063.       continue;
  1064.     }
  1065.       }
  1066.       /* Do not know it, not even in the compiler directory */
  1067.       KMDTrace("Locate", 4, "Negative confirmation for OID 0x%05x\n",
  1068.            list[i].theOID);
  1069.     } else {
  1070.       /* Put in our own location information */
  1071.       KMDTrace("FixMe", 3, "Fix me: need to confirm move\n");
  1072.       list[j].theLocation    = theODP->G.ownLoc;
  1073.       list[j].theOID         = theODP->G.ownOID;
  1074.       KMDTrace("Locate", 4, "Shout reply for OID 0x%05x: @ 0x%05x\n",
  1075.            theODP->G.ownOID, theODP->G.ownLoc);
  1076.       j++;
  1077.     }
  1078.   }
  1079.  
  1080.   if (j == 0) {
  1081.     /* None found here */
  1082.     KMDTrace("Locate", 4, "No OIDs found so no reply\n");
  1083.     return;
  1084.   }
  1085.  
  1086.   fHdr.size    = sizeof(fHdr) + j*sizeof(list[0]);
  1087.   SendLocateReply(fHandlePtr, fHdr, ShoutReplyITag);
  1088. }
  1089.  
  1090.  
  1091.  
  1092. /*
  1093.  * SearchItemHandler
  1094.  */
  1095. HResult SearchItemHandler(fHandlePtr, fHdr)
  1096. LMHandlePtr     fHandlePtr;
  1097. ItemHdr         fHdr;
  1098. {
  1099.   int count, i;
  1100.   register OID  theOID;
  1101.   register ODP  theODP;
  1102.   register GODP theObj;
  1103.  
  1104.   KMDTrace("Locate",3, "Search Item from %d\n",(*fHandlePtr)->mmMsgHdr.MsgSrc);
  1105.  
  1106.   count = UnpackLocateItem(fHandlePtr,fHdr);
  1107.   for (i = 0; i < count; i++) {
  1108.     KMDTrace("Locate", 4, "Search OID 0x%05x @ 0x%05x\n", list[i].theOID,
  1109.          list[i].theLocation);
  1110.     theOID = list[i].theOID;
  1111.     theODP = OTLookup(theOID);
  1112.     if (IsNULL(theODP)) {
  1113.       if ((((unsigned int) list[i].theOID >> 24) & 0xFF) == 0xFF) {
  1114.     /* Check on own disk */
  1115.     if (CheckOnDisk(list[i].theOID)) {
  1116.       KMDTrace("Locate", 3, "Found %s on disk.\n",
  1117.            PPOID(list[i].theOID));
  1118.       list[i].theLocation = thisNodeLocation;
  1119.       list[i].theOID  = list[i].theOID;
  1120.       continue;
  1121.     }
  1122.       } else if (((theOID >> 24) & 0xFF) == 0xFE) {
  1123.     KMDTrace("Locate", 4, "Trying on disk\n");
  1124.     if (CheckOnDisk(theOID)) {
  1125.       KMDTrace("Locate", 3,
  1126.            "Found on disk, scheduling crank up of it\n");
  1127.       /* Create a GOD entry for it */
  1128.       theObj = CreateGODEntry(theOID, (OID) NULL);
  1129.       theObj->ownLoc = thisNodeLocation;
  1130.       theObj->tag.isResident = TRUE;
  1131.       theObj->tag.setUpDone = FALSE;
  1132.       KMDTrace("Create", 3, "GOD for Cheating object %s\n",PPGOID(theOID));
  1133.       HoldSigs();
  1134.       QueueTask((HandlerPtr)CheatingCrankupHandler, (char *)theOID);
  1135.       ReleaseSigs();
  1136.       list[i].theLocation = thisNodeLocation;
  1137.       continue;
  1138.     }
  1139.       }
  1140.       KMDTrace("Locate", 4, "Negative search reply for OID 0x%05x\n",
  1141.            list[i].theOID);
  1142.       list[i].theLocation    = (EmLocation) NULL;
  1143.     } else {
  1144.       /* Put in our own location information */
  1145.       KMDTrace("FixMe", 3, "Fix me: need to confirm move\n");
  1146.       list[i].theLocation    = theODP->G.ownLoc;    
  1147.       KMDTrace("Locate", 4, "Search reply for OID 0x%05x: @ 0x%05x\n",
  1148.            theODP->G.ownOID, theODP->G.ownLoc);
  1149.     }
  1150.   }
  1151.   SendLocateReply(fHandlePtr, fHdr, SearchReplyITag);
  1152. }
  1153.  
  1154.  
  1155. /*
  1156.  * ConfirmReplyItemHandler
  1157.  */
  1158. HResult ConfirmReplyItemHandler(fHandlePtr, fHdr)
  1159. LMHandlePtr     fHandlePtr;
  1160. ItemHdr         fHdr;
  1161. {
  1162.   int count, i;
  1163.   short int msgSrc;
  1164.  
  1165.   msgSrc = (*fHandlePtr)->mmMsgHdr.MsgSrc;
  1166.   KMDTrace("Locate", 3, "Confirm Reply Item from %d\n", msgSrc);
  1167.  
  1168.   count = UnpackLocateItem(fHandlePtr,fHdr);
  1169.   for (i = 0; i < count; i++) {
  1170.     KMDTrace("Locate", 4, "Confirm OID 0x%05x @ 0x%05x\n", list[i].theOID,
  1171.          list[i].theLocation);
  1172.     UpdateLocation(list[i].theOID, list[i].theLocation, msgSrc);
  1173.   }
  1174. }
  1175.  
  1176.  
  1177. /*
  1178.  * ShoutReplyItemHandler
  1179.  */
  1180. HResult ShoutReplyItemHandler(fHandlePtr, fHdr)
  1181. LMHandlePtr fHandlePtr;
  1182. ItemHdr     fHdr;
  1183. {
  1184.   short int msgSrc;
  1185.  
  1186.   msgSrc = (*fHandlePtr)->mmMsgHdr.MsgSrc;
  1187.   KMDTrace("Locate", 3, "Shout Reply Item from %d\n",msgSrc);
  1188.   ConfirmReplyItemHandler(fHandlePtr, fHdr);
  1189. }
  1190.  
  1191.  
  1192. /*
  1193.  * SearchReplyItemHandler
  1194.  */
  1195. HResult SearchReplyItemHandler(fHandlePtr, fHdr)
  1196. LMHandlePtr fHandlePtr;
  1197. ItemHdr     fHdr;
  1198. {
  1199.   short int msgSrc;
  1200.  
  1201.   msgSrc = (*fHandlePtr)->mmMsgHdr.MsgSrc;
  1202.   KMDTrace("Locate", 3, "Search Reply Item from %d\n", msgSrc);
  1203.   ConfirmReplyItemHandler(fHandlePtr, fHdr);
  1204. }
  1205.  
  1206. /************************************************************************/
  1207. /************************************************************************/
  1208. /*
  1209.  * AddReqToTTable
  1210.  *
  1211.  * Add the necessary information to the LMMsg given for sending the given
  1212.  * Request across the network.  Enter the Req in the Sent Map.
  1213.  */
  1214. void AddReqToTTable(fHandlePtr, fReq, fSentMap, fARSet)
  1215. LMHandle  *fHandlePtr;
  1216. GenericPtr fReq;
  1217. Map fSentMap;
  1218. Set fARSet;
  1219. {
  1220.   TTableEntry entry;
  1221.   ReqHdr hdr;
  1222.  
  1223.   hdr = ((GenericReqPtr) fReq)->hdr;
  1224.  
  1225.   KMDTrace("TT", 5, "TT: Request RTag: %s\n", PPRTag(hdr.rTag));
  1226.  
  1227.   switch (hdr.rTag) {
  1228.  
  1229.   case InvokeRTag: {
  1230.     register TTInvokeReqEntry  *tReq    = (TTInvokeReqEntry *) &entry;
  1231.     register InvokeReqPtr       req     = (InvokeReqPtr) fReq;
  1232.  
  1233.     tReq->hdr.itemTag       = TTInvokeITag;
  1234.     tReq->hdr.size          = sizeof(TTInvokeReqEntry);
  1235.     tReq->oldODP            = (ODP) fReq;
  1236.     tReq->callerSSOID       = req->i.callerSSOID;
  1237.     tReq->callerLoc         = req->i.callerLoc;
  1238.     tReq->argumentCount     = req->i.argumentCount;
  1239.     tReq->resultCount       = req->i.resultCount;
  1240.     tReq->processOID        = req->i.processOID;
  1241.     tReq->targetOID         = req->i.targetOID;
  1242.     tReq->targetTryAtLoc    = req->i.targetTryAtLoc;
  1243.     Map_Insert(fSentMap, (int) req, (int) RefSent);
  1244.     AddToTTable(fHandlePtr, (ODP) req->targetGODP, fSentMap, fARSet);
  1245.     break;
  1246.   }
  1247.   case IncomingIRTag: {
  1248.     register TTIncomingIReqEntry *tReq  = (TTIncomingIReqEntry *) &entry;
  1249.     register IncomingIReqPtr       req  = (IncomingIReqPtr) fReq;
  1250.  
  1251.     tReq->hdr.itemTag       = TTIncomingIITag;
  1252.     tReq->hdr.size          = sizeof(TTIncomingIReqEntry);
  1253.     tReq->oldODP            = (ODP) fReq;
  1254.     tReq->callerSSOID       = req->i.callerSSOID;
  1255.     tReq->callerLoc         = req->i.callerLoc;
  1256.     tReq->argumentCount     = req->i.argumentCount;
  1257.     tReq->resultCount       = req->i.resultCount;
  1258.     tReq->processOID        = req->i.processOID;
  1259.     tReq->targetOID         = req->i.targetOID;
  1260.     tReq->targetTryAtLoc    = req->i.targetTryAtLoc;
  1261.  
  1262.     KMDTrace("FixMe", 3, "AddReqToTTable should respect visitors!!\n");
  1263.     if (NonNULL(req->visitorSet)) Set_Destroy(req->visitorSet);
  1264.  
  1265.     AddToTTable(fHandlePtr, OTLookup(req->i.callerSSOID), fSentMap, fARSet);
  1266.     break;
  1267.   }
  1268.   case LocateRTag:
  1269.   case MoveRTag:
  1270.   case StackBreakRTag:
  1271.   case CompilerLoadRTag:
  1272.   case CodeLoadRTag:
  1273.   case CheatingLoadRTag:
  1274.   case InitiallyRTag:
  1275.   case ConformRTag:
  1276.   case ViewRTag:
  1277.   case IncomingMoveRTag:
  1278.     break;
  1279.   default:
  1280.     ErrMsg("Bad RTag %s in AddReqToTTable\n", PPRTag(hdr.rTag));
  1281.     abort();
  1282.   }
  1283.   LMPutData(fHandlePtr, &entry, entry.TT.GO.hdr.size);
  1284. }
  1285.  
  1286.  
  1287.  
  1288. /*
  1289.  * AddToTTable
  1290.  * Adds an ODP to the translation table
  1291.  *
  1292.  * Add the necessary information to the LMMsg given for sending the given
  1293.  * ODP across the network.  Enter the ODP in the Sent Map.
  1294.  * Do only once for each ODP -- ignore duplicate requests
  1295.  *
  1296.  * Local garbage collection support, 3/17/89 cjeffery
  1297.  * We set the xref bit whenever we add anything to any ttable.
  1298.  */
  1299. void AddToTTable(fHandlePtr, fODP, fSentMap, fARSet)
  1300. LMHandle    *fHandlePtr;
  1301. register ODP fODP;
  1302. Map fSentMap;
  1303. Set fARSet;
  1304. {
  1305.   char kmddest[8];
  1306.   
  1307.   strcpy(kmddest,ISCHECKPOINT?"CPTT":"TT");
  1308.  
  1309.   if (fODP == (ODP) EMNIL) {
  1310.     KMDTrace(kmddest, 5, "AddToTTable(EMNIL) -- ignored\n");
  1311.     return;
  1312.   }
  1313.   if (NonNIL(Map_Lookup(fSentMap, (int) fODP))) {
  1314.     KMDTrace(kmddest, 5, "AddTT 0x%05x (tag %s) already in table\n", fODP,
  1315.          PPODBasicTag(fODP->G.tag.tag));
  1316.     return;
  1317.   }
  1318.   fODP->G.tag.seenHere = TRUE;
  1319.   KMDTrace(kmddest, 5, "AddTT: ODP 0x%06x \ttag %s\n", fODP,
  1320.        PPODBasicTag(fODP->G.tag.tag));
  1321.  
  1322.   /* turn on the xref bit; we're adding to the ttable */
  1323.   fODP->G.tag.xref = 1;
  1324.  
  1325.   switch (fODP->G.tag.tag) {
  1326.  
  1327.   case GODTag:
  1328.     if (IsNULL(fODP->G.ownOID)) {      /* Baptise and insert into OT */
  1329.       OTInsert(fODP);
  1330.     }
  1331.  
  1332.     godEntry.tag                = fODP->G.tag;
  1333.     godEntry.oldODP             = fODP;
  1334.     godEntry.ownOID             = fODP->G.ownOID;
  1335.     godEntry.ownLoc             = fODP->G.ownLoc;
  1336.     godEntry.myCodeOID          = fODP->G.myCodeOID;
  1337.  
  1338.     KMDTrace(kmddest, 4, "AddTT: GOD : 0x%08.8x (0x%05x) @ 0x%04x Code: %s\n",
  1339.          fODP->G.ownOID, fODP, fODP->G.ownLoc, PPCOID(fODP->G.myCodeOID));
  1340.  
  1341.     if (ISCHECKPOINT) CP_writeCompiledCodeFile(fODP->G.myCodeOID);
  1342.  
  1343.     PUTDATA(fHandlePtr, &godEntry, sizeof(godEntry));
  1344.     Map_Insert(fSentMap, (int) fODP, (int) RefSent);
  1345.     break;
  1346.  
  1347.  
  1348.   case SSODTag:
  1349.  
  1350. /*CP:should we baptise these??*/
  1351.     if (!fODP->SS.ownOID){
  1352.       /* Baptise and insert into OT */
  1353.       OTInsert(fODP);
  1354.     }
  1355.     ssodEntry.oldODP      = fODP;
  1356.     ssodEntry.tag         = fODP->SS.tag;
  1357.     ssodEntry.ownOID      = fODP->SS.ownOID;
  1358.     ssodEntry.ownLoc      = fODP->SS.ownLoc;
  1359.     ssodEntry.processOID  = 
  1360.       (IsNULL(fODP->SS.dataPtr) || IsNIL(fODP->SS.dataPtr)) ? EMNIL : fODP->SS.dataPtr->processOID;
  1361.     KMDTrace(kmddest, 4,
  1362.          "AddTT: SSOD: 0x%08.8x (0x%05x) @ 0x%04x, Process: 0x%05x\n",
  1363.          fODP->SS.ownOID, fODP, fODP->SS.ownLoc,
  1364.          ssodEntry.processOID);
  1365.     PUTDATA(fHandlePtr, &ssodEntry, sizeof(ssodEntry));
  1366.     Map_Insert(fSentMap, (int) fODP, (int)RefSent);
  1367.     break;
  1368.  
  1369.     
  1370.   case CodeODTag:
  1371.     codeodEntry.oldODP   = (ODP) fODP->C.dataPtr;
  1372.     codeodEntry.tag      = fODP->C.tag;
  1373.     codeodEntry.ownOID   = fODP->C.ownOID;
  1374.     codeodEntry.ownLoc   = fODP->C.ownLoc;
  1375.     KMDTrace(kmddest, 4, "AddTT: C OD: (dataptr 0x%05x) @ 0x%02x %s\n",
  1376.          fODP->C.dataPtr, fODP->C.ownLoc, PPCOID(fODP->C.ownOID));
  1377.     /*bosch*/
  1378.     PUTDATA(fHandlePtr, &codeodEntry, sizeof(codeodEntry));
  1379.     Map_Insert(fSentMap, (int) fODP, (int)RefSent);
  1380.     break;
  1381.  
  1382.  
  1383.   case GODataTag:
  1384.     KMDTrace("FixMe", 2,
  1385.          "AddToTT: recoverable compiler bug: tag should be LOTag\n");
  1386.     /* Fix the problem and continue !!!!!!*/
  1387.     fODP->L.tag.tag             = LOTag;
  1388.     /* Fall thru to LOTag !!! */
  1389.  
  1390.   case LOTag: {
  1391.     register CodePtr theCodePtr = fODP->L.myCodePtr;
  1392.  
  1393.     assert (NonNULL(theCodePtr));
  1394.     if (!theCodePtr->tag.replicated) {
  1395.       ErrMsg("AddTT: LO  : must be replicated\n");
  1396.       abort();
  1397.     }
  1398.     /* and now the same as move */
  1399.     MoveToTTable(fHandlePtr, fODP, fSentMap, fARSet);
  1400.     break;
  1401.   }
  1402.  
  1403.   case AbConTag:
  1404.     abconEntry.tag              = fODP->AB.tag;
  1405.     abconEntry.oldODP           = fODP;
  1406.     abconEntry.ATOID            = fODP->AB.ATOID;
  1407.     abconEntry.restrictOID      = fODP->AB.restrictOID;
  1408.     abconEntry.CodeOID          = fODP->AB.CodeOID;
  1409.     KMDTrace(kmddest, 4, "AddTT: AbCon(0x%05x): AT %s rAT %s CT %s\n",
  1410.          fODP, PPCOID(fODP->AB.ATOID), PPCOID(fODP->AB.restrictOID),
  1411.          PPCOID(fODP->AB.CodeOID));
  1412.     PUTDATA(fHandlePtr, &abconEntry, sizeof(abconEntry));
  1413.     Map_Insert(fSentMap, (int) fODP, (int)RefSent);
  1414.     break;
  1415.  
  1416.  
  1417.   case CondTag:
  1418.     if (IsNULL(fODP->CD.ownOID)) {    /* Baptise and insert into OT */
  1419.       OTInsert(fODP);
  1420.     }
  1421.  
  1422.     condEntry.tag               = fODP->CD.tag;
  1423.     condEntry.oldODP            = fODP;
  1424.     condEntry.ownOID            = fODP->CD.ownOID;
  1425.     condEntry.ownLoc            = fODP->CD.ownLoc;
  1426.  
  1427.     KMDTrace(kmddest, 4, "AddTT: CondOD: %s (0x%05x) @ %s\n",
  1428.          PPOID(fODP->CD.ownOID), fODP, PPLoc(fODP->CD.ownLoc));
  1429.     PUTDATA(fHandlePtr, &condEntry, sizeof(condEntry));
  1430.     Map_Insert(fSentMap, (int) fODP, (int) RefSent);
  1431.     break;
  1432.  
  1433.  
  1434.   default:
  1435.     ErrMsg("Cannot AddTT: tag %s\n", PPODBasicTag(fODP->G.tag.tag));
  1436.     abort();
  1437.   }
  1438. }
  1439.  
  1440.  
  1441.  
  1442. /*
  1443.  * TranslateVar
  1444.  */
  1445. void TranslateVar(fVarPtr, fTMap)
  1446. AVariablePtr fVarPtr;
  1447. Map          fTMap;
  1448. {
  1449.   register AVariablePtr v = fVarPtr;
  1450.   register AbConPtr     oldAbConPtr, newAbConPtr;
  1451.   register DataAddr     oldAddr;
  1452.  
  1453.   if (IsNIL(v->myAbConPtr)) {
  1454.     KMDTrace("TT", 5, "TT: Var is NIL\n");
  1455.   } else {
  1456.     /* Translate AbCon */
  1457.     oldAbConPtr     = v->myAbConPtr;
  1458.     newAbConPtr     = (AbConPtr) Map_Lookup(fTMap, (int) oldAbConPtr);
  1459.     v->myAbConPtr   = newAbConPtr;
  1460.     assert(NonNIL(newAbConPtr));
  1461.     if (IsNIL(v->myAddr)) {
  1462.       KMDTrace("TT", 5, "TT: Var is NIL; viewed as %s\n",
  1463.            PPCOID(newAbConPtr->ATOID));
  1464.     } else if (newAbConPtr->tag.hasNoPointer) {
  1465.       KMDTrace("TT", 5, "TT: Var is data: %d; one of %s viewed as %s\n",
  1466.            v->myAddr, PPCOID(v->myAbConPtr->CodeOID),
  1467.            PPCOID(v->myAbConPtr->ATOID));
  1468.     } else {
  1469.       /* Translate ODP */
  1470.       oldAddr     = v->myAddr;
  1471.       v->myAddr   = (SSAddr) Map_Lookup(fTMap, (int) v->myAddr);
  1472.       KMDTrace("TT", 5, "TT: Var (0x%06x -> 0x%06x) one of %s; viewed as %s\n",
  1473.            oldAddr, v->myAddr, PPCOID(newAbConPtr->CodeOID),
  1474.            PPCOID(newAbConPtr->ATOID));
  1475.     }
  1476.   }
  1477. }
  1478.  
  1479.  
  1480.  
  1481. /*
  1482.  * AddVarToTTable
  1483.  */
  1484. void AddVarToTTable(fHandlePtr, fVarPtr, fSentMap, fARSet)
  1485. LMHandle    *fHandlePtr;
  1486. AVariablePtr fVarPtr;
  1487. Map          fSentMap;
  1488. Set          fARSet;
  1489. {
  1490.   register AVariablePtr v = fVarPtr;
  1491.   char kmddest[8];
  1492.   strcpy(kmddest,ISCHECKPOINT?"CPTT":"TT");
  1493.  
  1494.   if (IsNIL(v->myAbConPtr)) {
  1495.     KMDTrace(kmddest, 5, "TT: Var is NIL\n");
  1496.   } else if (IsNIL(v->myAddr)) {
  1497.     KMDTrace(kmddest, 5, "TT: Var is NIL (viewed as %s)\n",
  1498.          PPCOID(v->myAbConPtr->ATOID));
  1499.     AddToTTable(fHandlePtr,(ODP) v->myAbConPtr, fSentMap, fARSet);
  1500.   } else if (v->myAbConPtr->tag.hasNoPointer) {
  1501.     KMDTrace(kmddest, 5, "TT: Var is data: %d; one of %s\n", v->myAddr,
  1502.          PPCOID(v->myAbConPtr->CodeOID));
  1503.     AddToTTable(fHandlePtr,(ODP) v->myAbConPtr, fSentMap, fARSet);
  1504.   } else {
  1505.     KMDTrace(kmddest, 5, "TT: Var is 0x%05x; one of %s viewed as %s\n",
  1506.          v->myAddr, PPCOID(v->myAbConPtr->CodeOID),
  1507.          PPCOID(v->myAbConPtr->ATOID));
  1508.     AddToTTable(fHandlePtr,(ODP) v->myAbConPtr, fSentMap, fARSet);
  1509.     AddToTTable(fHandlePtr, (ODP) v->myAddr, fSentMap, fARSet);
  1510.   }
  1511. }
  1512.  
  1513.  
  1514.  
  1515. /*
  1516.  * MoveVarToTTable
  1517.  */
  1518. void MoveVarToTTable(fHandlePtr, fVarPtr, fSentMap, fARSet)
  1519. LMHandle    *fHandlePtr;
  1520. AVariablePtr fVarPtr;
  1521. Map fSentMap;
  1522. Set fARSet;
  1523. {
  1524.   register AVariablePtr v = fVarPtr;
  1525.   char kmddest[8];
  1526.   strcpy(kmddest,ISCHECKPOINT?"CPTT":"TT");
  1527.  
  1528.   if (IsNIL(v->myAbConPtr)) {
  1529.     KMDTrace(kmddest, 5, "TT: Var is NIL\n");
  1530.   } else if (IsNIL(v->myAddr)) {
  1531.     KMDTrace(kmddest, 5, "TT: Var is NIL (viewed as %s)\n",
  1532.          PPCOID(v->myAbConPtr->CodeOID));
  1533.     AddToTTable(fHandlePtr,(ODP) v->myAbConPtr, fSentMap, fARSet);
  1534.   } else if (v->myAbConPtr->tag.hasNoPointer) {
  1535.     KMDTrace(kmddest, 5, "Var is data: %d; one of %s\n", v->myAddr,
  1536.          PPCOID(v->myAbConPtr->CodeOID));
  1537.     AddToTTable(fHandlePtr,(ODP) v->myAbConPtr, fSentMap, fARSet);
  1538.   } else {
  1539.     KMDTrace(kmddest, 5, "Var is 0x%05x; one of %s viewed as %s\n",
  1540.          v->myAddr, PPCOID(v->myAbConPtr->CodeOID),
  1541.          PPCOID(v->myAbConPtr->ATOID));
  1542.     AddToTTable(fHandlePtr,(ODP) v->myAbConPtr, fSentMap, fARSet);
  1543.     MoveToTTable(fHandlePtr, (ODP) v->myAddr, fSentMap, fARSet);
  1544.   }
  1545. }
  1546.  
  1547.  
  1548.  
  1549. /*
  1550.  * AddCodeAddrToTTable
  1551.  */
  1552. void AddCodeAddrToTTable(fHandlePtr, fCodePtr, fIP, fSentMap, fARSet)
  1553. LMHandle *fHandlePtr;
  1554. CodePtr   fCodePtr;
  1555. CodeAddr  fIP;
  1556. Map fSentMap;
  1557. Set fARSet;
  1558. {
  1559.   int       kernelOpNumber;
  1560.   Offset    theOffset;
  1561.   RefStatus status;
  1562.  
  1563.   status = (RefStatus) Map_Lookup(fSentMap, (int) fIP);
  1564.  
  1565.   if ((int) status != EMNIL) {
  1566.     KMDTrace("TT", 5, "AddTT 0x%05x already in map\n", fIP);
  1567.     return;
  1568.   }
  1569.  
  1570.   Map_Insert(fSentMap, (int) fIP, (int)RefSent);
  1571.  
  1572.   if (IsNULL(fCodePtr)) {
  1573.     /* It is an address of a return-to-kernel routine */
  1574.     kernelOpNumber      = Map_Lookup(KernelReturnAddressMap, (int) fIP);
  1575.     if (IsNIL(kernelOpNumber)) {
  1576.       ErrMsg("Bad IP 0x%06x in AddCodeAddrToTTable\n", fIP);
  1577.       abort();
  1578.     }
  1579.     codeaddrEntry.oldODP        = (ODP) fIP;
  1580.     codeaddrEntry.theCodeOID    = (OID) NULL;
  1581.     codeaddrEntry.theOffset     = (Offset) kernelOpNumber;
  1582.     KMDTrace("TT", 4, "AddTT: 0x%06x Kernel op number #%d\n", fIP,
  1583.          kernelOpNumber);
  1584.     LMPutData(fHandlePtr, &codeaddrEntry, sizeof(codeaddrEntry));
  1585.   } else {
  1586.     AddToTTable(fHandlePtr, OTLookup(fCodePtr->ownOID), fSentMap, fARSet);
  1587.     /* It is an address in Emerald compiled code. */
  1588.     codeaddrEntry.oldODP        = (ODP) fIP;
  1589.     codeaddrEntry.theCodeOID    = (OID) fCodePtr->ownOID;
  1590.     theOffset                   = (Offset) byteOffset(fCodePtr, fIP);
  1591.     codeaddrEntry.theOffset     = theOffset;
  1592.     KMDTrace("TT", 4, "AddTT: Code Addr 0x%06x (%d) in %s, line %s\n",
  1593.          fIP, theOffset, PPCodePtr(fCodePtr), PPFindLineNo(fCodePtr, fIP));
  1594.     LMPutData(fHandlePtr, &codeaddrEntry, sizeof(codeaddrEntry));
  1595.   }
  1596. }
  1597.  
  1598.  
  1599.  
  1600. /*
  1601.  * MoveToTTable
  1602.  *
  1603.  * Add the necessary information to the LMMsg given for sending the given
  1604.  * ODP across the network.  Enter the ODP in the SentMap.
  1605.  * Enter any ARs that are to move in the fARSet.
  1606.  * Do only once for each ODP -- ignore duplicate requests
  1607.  *
  1608.  * Checkpoint support merged 7/22/88 cjeffery
  1609.  * A null fHandlePtr => we are doing a checkpoint.  This is used throughout
  1610.  * the move delivery subsystem.
  1611.  *
  1612.  * Local garbage collection support added 3/17/89 cjeffery
  1613.  * We set the xref bit whenever we move anything anywhere.
  1614.  */
  1615. void MoveToTTable(fHandlePtr, fODP, fSentMap, fARSet)
  1616. LMHandle    *fHandlePtr;
  1617. register ODP fODP;
  1618. Map          fSentMap;
  1619. Set          fARSet;
  1620. {
  1621.   NodeNum   destLNN;
  1622.   RefStatus status;
  1623.   int        instanceSize;
  1624.   char kmddest[12], kmdttdest[8];
  1625.   strcpy(kmddest,ISCHECKPOINT ? "Checkpoint": "Move");
  1626.   strcpy(kmdttdest,ISCHECKPOINT ? "CPTT": "TT");
  1627.  
  1628.   if (fODP == (ODP) EMNIL) {
  1629.     KMDTrace(kmdttdest, 5, "MoveToTTable(EMNIL) -- ignored\n");
  1630.     return;
  1631.   }
  1632.   status = (RefStatus) Map_Lookup(fSentMap, (int) fODP);
  1633.  
  1634.   if (((int) status != EMNIL) && (status == RefMoved) ) {
  1635.     KMDTrace(kmdttdest, 5, "MoveTT 0x%05x already %sd\n", fODP, kmddest);
  1636.     return;
  1637.   }
  1638.  
  1639.   Map_Insert(fSentMap, (int) fODP, (int)RefMoved);
  1640.   fODP->G.tag.seenHere    = TRUE;    
  1641.  
  1642.   if(!ISCHECKPOINT) destLNN = (*fHandlePtr)->mmMsgHdr.MsgDest;
  1643.  
  1644.   /* turn on the xref bit; if it moves we won't collect it! */
  1645.   fODP->G.tag.xref = 1;
  1646.  
  1647.   switch (fODP->G.tag.tag) {
  1648.  
  1649.   case GODTag: {
  1650.     register CodePtr theCodePtr;
  1651.     register GODP    x;
  1652.     AbConPtr         theAbCon;
  1653.     CodeODP          theCodeODP;
  1654.     
  1655.     x = &fODP->G;
  1656.     if (!x->tag.isResident) {
  1657.       if(ISCHECKPOINT){
  1658.     KMDTrace("Checkpoint", 2,
  1659.          "Process %s fails, 0x%05x nonresident; unavailable in %s\n",
  1660.          PPPOID(currentSSP->processOID), fODP, PPSSPlace(currentSSP));
  1661.  
  1662.     /* Checkpoint does an unavailable exception if an object
  1663.      * being Checkpointed is not resident.
  1664.      */
  1665.     theAbCon = OIDOIDOIDToAbCon(x->dataPtr->myCodePtr->ownAbstractType,
  1666.                     (OID)EMNIL,
  1667.                     x->dataPtr->myCodePtr->ownOID);
  1668.     unavail(preemptRunning(), x, theAbCon);
  1669.     return;
  1670.       } else { /* !ISCHECKPOINT */
  1671.     fetchgodEntry.tag                = fODP->G.tag;
  1672.     fetchgodEntry.oldODP             = fODP;
  1673.     fetchgodEntry.ownOID             = fODP->G.ownOID;
  1674.     fetchgodEntry.ownLoc             = fODP->G.ownLoc;
  1675.     fetchgodEntry.myCodeOID          = fODP->G.myCodeOID;
  1676.     KMDTrace("TT", 4, "AddTT: FetchGOD : %s (0x%05x) @ %s Code: %s\n",
  1677.          PPGOID(fODP->G.ownOID), fODP, PPLoc(fODP->G.ownLoc),
  1678.          PPCOID(fODP->G.myCodeOID));
  1679.     LMPutData(fHandlePtr, &fetchgodEntry, sizeof(fetchgodEntry));
  1680.     Map_Insert(fSentMap, (int) fODP, (int)RefSent);
  1681.     break;
  1682.       }
  1683.     }
  1684.     
  1685.     theCodePtr = fODP->G.dataPtr->myCodePtr;
  1686.     theCodeODP = (CodeODP) OTLookup(theCodePtr->ownOID);
  1687.  
  1688.     /* Ensure that CodeODP is sent along */
  1689.     MoveToTTable(fHandlePtr, (ODP) theCodeODP, fSentMap, fARSet);
  1690.  
  1691.     if (IsNULL(fODP->G.ownOID)) {      /* Baptise and insert into OT */
  1692.       OTInsert(fODP);
  1693.       KMDTrace(kmdttdest, 5,
  1694.          "%sTT: assigning OID %s to global object 0x%04x\n",
  1695.          kmddest,PPOID(fODP->G.ownOID), fODP);
  1696.     }
  1697.  
  1698.     /* Commit the move */
  1699.     if(ISCHECKPOINT) {
  1700. #ifdef UNDEF
  1701. /*    fODP->G.tag.frozen          = TRUE; if we do this, where to undo it??*/
  1702.       fODP->G.tag.isFixed         = TRUE;
  1703. #endif
  1704.     } else {
  1705.       fODP->G.tag.isResident = FALSE;
  1706.       fODP->G.tag.frozen     = TRUE;
  1707.       fODP->G.ownLoc         = 
  1708.     mMakeLocation(destLNN, ((mGetLocTimeStamp(fODP->G.ownLoc)) + 1));
  1709.     }
  1710.  
  1711.     instanceSize = theCodePtr->instanceSize;
  1712.     if (instanceSize < 0) {
  1713.       instanceSize = FindVectorSize((VectorPtr) (fODP->G.dataPtr));
  1714.       KMDTrace("Vector", 4, "Vector Instance size %d\n", instanceSize);
  1715.       if ((instanceSize % sizeof(ODP)) != 0) {
  1716.     /* Round up */
  1717.     instanceSize += sizeof(ODP) - (instanceSize % sizeof(ODP));
  1718.     KMDTrace(kmdttdest,4, "\tSize rounded up to %d bytes\n", instanceSize);
  1719.       }
  1720.     }
  1721.  
  1722.     movegodEntry.hdr.size       = sizeof(movegodEntry) + instanceSize;
  1723.     movegodEntry.tag            = fODP->G.tag;
  1724.     movegodEntry.oldODP         = fODP;
  1725.     movegodEntry.ownOID         = fODP->G.ownOID;
  1726.     movegodEntry.ownLoc         = fODP->G.ownLoc;
  1727.     movegodEntry.myCodeOID      = fODP->G.myCodeOID;
  1728.     movegodEntry.oldGODataPtr   = fODP->G.dataPtr;
  1729.     KMDTrace(kmddest, 3,
  1730.          "Moving GOD %s to %s, one of %s\n", PPGOID(fODP->G.ownOID),
  1731.          PPLoc(fODP->G.ownLoc), PPCOID(fODP->G.myCodeOID));
  1732.     KMDTrace(kmdttdest, 4, "MoveTT: GOD: %s (0x%05x) @ %s Code: %s\n",
  1733.          PPGOID(fODP->G.ownOID), fODP, PPLoc(fODP->G.ownLoc),
  1734.          PPCOID(fODP->G.myCodeOID));
  1735.     if (ISCHECKPOINT) CP_writeCompiledCodeFile(fODP->G.myCodeOID);
  1736.     PUTDATA(fHandlePtr, &movegodEntry, sizeof(movegodEntry));
  1737.     PUTDATA(fHandlePtr, fODP->G.dataPtr, instanceSize);
  1738.  
  1739.     /* Traverse and send components */
  1740.     TraverseAndMove(fHandlePtr, (ODP) fODP->G.dataPtr, fSentMap, fARSet);
  1741.  
  1742.     /* Traverse AR list and send components */
  1743.     if(!ISCHECKPOINT) TraverseAndMoveARList(&fODP->G, fARSet);
  1744.  
  1745.     break;
  1746.   }
  1747.  
  1748.   case CodeODTag: {
  1749.     movecodeodEntry.oldODP = (ODP) fODP->C.dataPtr;
  1750.     movecodeodEntry.tag    = fODP->C.tag;
  1751.     movecodeodEntry.ownOID = fODP->C.ownOID;
  1752.     movecodeodEntry.ownLoc = fODP->C.ownLoc;
  1753.     KMDTrace(kmdttdest, 4, "MoveTT: C OD: 0x%04x (dataptr 0x%05x) @ 0x%04x\n",
  1754.          fODP->C.ownOID, fODP->C.dataPtr, fODP->C.ownLoc);
  1755.     PUTDATA(fHandlePtr, &movecodeodEntry, sizeof(movecodeodEntry));
  1756.     break;
  1757.   }
  1758.  
  1759.   case LOTag: {
  1760.     register CodePtr theCodePtr;
  1761.     CodeODP          theCodeODP;
  1762.     int              linstanceSize;
  1763.  
  1764.     theCodePtr = fODP->L.myCodePtr;
  1765.     assert (NonNULL(theCodePtr));
  1766.  
  1767.     theCodeODP = (CodeODP) OTLookup(theCodePtr->ownOID);
  1768.     if (ISCHECKPOINT) CP_writeCompiledCodeFile(theCodePtr->ownOID);
  1769.     AddToTTable(fHandlePtr, (ODP) theCodeODP, fSentMap, fARSet);
  1770.  
  1771.     KMDTrace(kmdttdest, 4, "MoveTT: LO  : (0x%05x) CT 0x%04x size %d, %s\n",
  1772.          fODP, theCodePtr->ownOID, theCodePtr->instanceSize, PPODP(fODP));
  1773.  
  1774.     if (fODP->L.tag.replicated) {
  1775.       register RODataPtr      theObj;
  1776.       theObj                  = (RODataPtr) fODP;
  1777.       if (IsNIL(theObj->ownOID) || IsNULL(theObj->ownOID)) {
  1778.     theObj->ownOID      = getNextOID();
  1779.     OTInsert((ODP) theObj);
  1780.     KMDTrace(kmdttdest, 5,
  1781.          "MoveTT: assinging OID %s to replicated object 0x%04x\n",
  1782.          PPOID(theObj->ownOID), theObj);
  1783.       }
  1784.     }
  1785.  
  1786.     linstanceSize = theCodePtr->instanceSize;
  1787.  
  1788.     KMDTrace(kmdttdest, 4, "\tSize %d bytes\n", linstanceSize);
  1789.     if (linstanceSize < 0) {
  1790.       /* Vector */
  1791.       linstanceSize = FindVectorSize((VectorPtr) fODP);
  1792.       KMDTrace(kmdttdest, 4, "\tSize %d bytes\n", linstanceSize);
  1793.       if ((linstanceSize % sizeof(ODP)) != 0) {
  1794.     /* Round up */
  1795.     linstanceSize += sizeof(ODP) - (linstanceSize % sizeof(ODP));
  1796.     KMDTrace(kmdttdest,4,"\tSize rounded up to %d bytes\n", linstanceSize);
  1797.       }
  1798.     }
  1799.  
  1800.     loEntry.hdr.size = linstanceSize + (sizeof(loEntry)-sizeof(ODTag));
  1801.     loEntry.oldODP = fODP;
  1802.     PUTDATA(fHandlePtr, &loEntry, sizeof(loEntry)-sizeof(ODTag));
  1803.     PUTDATA(fHandlePtr, fODP, linstanceSize);
  1804.  
  1805.     /* Traverse and send components */
  1806.     TraverseAndMove(fHandlePtr, fODP, fSentMap, fARSet);
  1807.     break;
  1808.   }
  1809.  
  1810.   case AbConTag: {
  1811.     abconEntry.tag              = fODP->AB.tag;
  1812.     abconEntry.oldODP           = fODP;
  1813.     abconEntry.ATOID            = fODP->AB.ATOID;
  1814.     abconEntry.restrictOID      = fODP->AB.restrictOID;
  1815.     abconEntry.CodeOID          = fODP->AB.CodeOID;
  1816.     KMDTrace(kmdttdest, 4, "MoveTT: AB  : AT 0x%04x  CT 0x%08x  (0x%05x)\n",
  1817.          fODP->AB.ATOID, fODP->AB.CodeOID, fODP);
  1818.     KMDTrace(kmdttdest, 5, "\t%s viewed as %s restricted to %s\n",
  1819.          PPCOID(fODP->AB.CodeOID), PPCOID(fODP->AB.ATOID),
  1820.          PPCOID(fODP->AB.restrictOID));
  1821.     PUTDATA(fHandlePtr, &abconEntry, sizeof(abconEntry));
  1822.     break;
  1823.   }
  1824.  
  1825.   default:
  1826.     ErrMsg("Cannot Move, tag %s\n", PPODBasicTag(fODP->G.tag.tag));
  1827.     abort();
  1828.   }
  1829. }
  1830.  
  1831.  
  1832.  
  1833. /*
  1834.  * DigestTable
  1835.  *
  1836.  * Read a translation table out of the message, stop when
  1837.  * either the msg is emptied or when a non-translation item is found.
  1838.  * Build a translation map: oldODP -> newODP for the things that
  1839.  * can be translated right now (everything except code that needs to be
  1840.  * loaded).
  1841.  * Build a load map of the Code OIDs that need to be loaded before
  1842.  * translation.  CTOID -> oldODP
  1843.  * Build a set, fNewSet, of the newly arrived data areas (excluding code
  1844.  * areas).  These areas are the ones that need to be translated.
  1845.  */
  1846. void DigestTable(fHandlePtr, fTMap, fLoadMap, fNewSet, isRecovery)
  1847. LMHandle *fHandlePtr;    /* replicantPtr if isRecovery */
  1848. Map fTMap, fLoadMap;
  1849. Set fNewSet;
  1850. int isRecovery;        /* TRUE implies we are doing RecoverDigestTable(); */
  1851. {
  1852.   register ODP     entry;
  1853.   register CodeODP codeEntry;
  1854.   int              length;
  1855.   TTableEntry      theEntry;
  1856.  
  1857.   register TTableEntryPtr t = &theEntry;
  1858.  
  1859.   KMDTrace("TT", 3, "%sDigestTable\n",isRecovery?"Recover":"");
  1860.     
  1861.   /* Get the Item hdr and the OD tag of the thing. */
  1862.   length  = sizeof(TTGenericEntry);
  1863.     
  1864.   GETDATA(fHandlePtr, t, &length);
  1865.   while ( (length == sizeof(TTGenericEntry))
  1866.      &&   ((int) t->TT.GO.hdr.itemTag > (int) TTFirstITag)
  1867.      &&   ((int) t->TT.GO.hdr.itemTag < (int) TTLastITag)) {
  1868.     KMDTrace("TT", 3, "ITag is %s, size %d bytes\n",
  1869.          PPITag(t->TT.GO.hdr.itemTag), t->TT.GO.hdr.size);
  1870.  
  1871.     switch (t->TT.GO.hdr.itemTag) {
  1872.  
  1873.     case TTGODITag: {
  1874.       /* Get rest of GODEntry */
  1875.       length = sizeof(TTGODEntry) - sizeof(TTGenericEntry);
  1876.       GETDATA(fHandlePtr, addOffset(t,sizeof(TTGenericEntry)), &length);
  1877.       entry = OTLookup(t->TT.GO.ownOID);
  1878.       if (IsNULL(entry)) {
  1879.     /* Insert a new entry */
  1880.     entry             = getFreeOD();
  1881.     entry->G.ownOID     = t->TT.GO.ownOID;
  1882.     entry->G.tag        = t->TT.GO.tag;
  1883.     entry->G.tag.frozen = TRUE;
  1884.     entry->G.tag.isResident = FALSE;
  1885.     entry->G.ownLoc     = t->TT.GO.ownLoc;
  1886.     entry->G.ARListHead.next = entry->G.ARListHead.prev =
  1887.       (InvokeQueuePtr) &entry->G.ARListHead;
  1888.     entry->G.myCodeOID  = t->TT.GO.myCodeOID;
  1889.     /* Lookup and insert code, if necessary */
  1890.     codeEntry = (CodeODP) OTLookup(t->TT.GO.myCodeOID);
  1891.     if (IsNULL(codeEntry)) {    /* Create an entry */
  1892.       codeEntry = CreateCodeODEntry(t->TT.GO.myCodeOID,t->TT.GO.ownLoc);
  1893.     } else {            /* Verify that it is a code entry */
  1894.       assert(codeEntry->tag.tag == CodeODTag);
  1895.     }
  1896.     OTInsert(entry);
  1897.       } else {
  1898.     assert (entry->G.tag.tag == t->TT.GO.tag.tag);
  1899.     /* Check to see if location timestamp is newer */
  1900.     if (LOCATIONNEWER(t->TT.GO.ownLoc, entry->SS.ownLoc)) {
  1901.       KMDTrace("TT", 3, "GO OID 0x%05x was @ 0x%04x now @ 0x%04x\n",
  1902.            entry->G.ownOID, entry->G.ownLoc, t->TT.GO.ownLoc);
  1903.       entry->G.ownLoc = t->TT.GO.ownLoc;
  1904.       KMDTrace("FixMe", 5, "Fix me: should reset ODTag flags.\n");
  1905.     }
  1906.       }
  1907.       Map_Insert(fTMap, (int) t->TT.GO.oldODP, (int) entry);
  1908.       KMDTrace("TT", 4,
  1909.            "TT GOD 0x%04x %-9.9s@0x%04x (0x%05x)->(0x%05x) CT 0x%05x\n",
  1910.            t->TT.GO.ownOID, BasicTagName[(int) t->TT.GO.tag.tag],
  1911.            t->TT.GO.ownLoc, t->TT.GO.oldODP, entry, t->TT.GO.myCodeOID);
  1912.       break;
  1913.     }
  1914.  
  1915.     case TTSSODITag: {
  1916.       if(isRecovery){
  1917.     ErrMsg("Should never get an SSODITag in RecoverDigestTable #1!");
  1918.     abort();
  1919.       } else {
  1920.     /* Get rest of Entry */
  1921.     length = sizeof(TTSSODEntry) - sizeof(TTGenericEntry);
  1922.     LMGetData(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)), &length);
  1923.     entry = (ODP) OTLookup(t->TT.SS.ownOID);
  1924.     if (IsNULL(entry)) {
  1925.       /* Insert new SSOD entry */
  1926.       entry = getFreeOD();
  1927.       entry->SS.tag               = t->TT.SS.tag;
  1928.       entry->SS.tag.isResident    = FALSE;
  1929.       entry->SS.ownOID            = t->TT.SS.ownOID;
  1930.       entry->SS.ownLoc            = t->TT.SS.ownLoc;
  1931.       entry->SS.processOID        = t->TT.SS.processOID;
  1932.       OTInsert(entry);
  1933.     } else {
  1934.       assert (entry->SS.tag.tag == t->TT.SS.tag.tag);
  1935.       /* Check to see if location timestamp is newer */
  1936.       if (LOCATIONNEWER(t->TT.SS.ownLoc, entry->SS.ownLoc)) {
  1937.         KMDTrace("TT", 3, "SS OID 0x%05x was @ 0x%04x now @ 0x%04x\n",
  1938.              entry->SS.ownOID, entry->SS.ownLoc, t->TT.SS.ownLoc);
  1939.         entry->SS.ownLoc = t->TT.SS.ownLoc;
  1940.         KMDTrace("FixMe", 3, "Fix me: should reset ODTag flags.\n");
  1941.       }
  1942.     }
  1943.     Map_Insert(fTMap, (int) t->TT.SS.oldODP, (int) entry);
  1944.     KMDTrace("TT", 4,
  1945.          "TT 0x%04x %-9.9s@0x%04x (0x%05x)->(0x%05x) Process %s\n",
  1946.          t->TT.SS.ownOID, BasicTagName[(int) t->TT.SS.tag.tag],
  1947.          t->TT.SS.ownLoc, t->TT.SS.oldODP, entry,
  1948.          PPPOID(t->TT.SS.processOID));
  1949.     break;
  1950.       }
  1951.     }
  1952.  
  1953.     case TTCodeODITag: {
  1954.       register CodeODP        theCodeODP;
  1955.       /* Get rest of Entry */
  1956.       length = sizeof(TTCEntry) - sizeof(TTGenericEntry);
  1957.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)), &length);
  1958.  
  1959.       assert (length == sizeof(TTCEntry) - sizeof(TTGenericEntry));
  1960.       theCodeODP = (CodeODP) OTLookup(t->TT.C.ownOID);
  1961.       if (IsNULL(theCodeODP)) {
  1962.     /* Create an entry for some unknown code object */
  1963.     theCodeODP = CreateCodeODEntry(t->TT.C.ownOID, t->TT.C.ownLoc);
  1964.       }
  1965.       if (!theCodeODP->tag.setUpDone) {
  1966.     Map_Insert(fLoadMap, (int) theCodeODP->ownOID, (int) t->TT.C.oldODP);
  1967.     KMDTrace("TT", 4, "TT C (0x%04x) do not have %s\n",
  1968.          t->TT.LO.oldODP, PPCOID(t->TT.C.ownOID));
  1969.       } else {
  1970.     KMDTrace("TT", 4, "TT C (0x%05x) -> (0x%05x)\n",
  1971.          t->TT.LO.oldODP, theCodeODP);
  1972.     Map_Insert(fTMap, (int) t->TT.C.oldODP, (int) theCodeODP->dataPtr);
  1973.       }
  1974.       break;
  1975.     }
  1976.  
  1977.     case TTLOITag: {
  1978.       int                instanceSize, residual;
  1979.       register LODataPtr newODP;
  1980.       register RODataPtr candidateODP;
  1981.         
  1982.       /* Get rest of Entry */
  1983.       residual = sizeof(TTLOEntry) - sizeof(TTGenericEntry);
  1984.       if (residual>0) {
  1985.     GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)), &residual);
  1986.     assert(residual == (sizeof(TTLOEntry)-sizeof(TTGenericEntry)));
  1987.       }
  1988.       instanceSize = t->TT.LO.hdr.size + (sizeof(ODTag)-sizeof(TTLOEntry));
  1989.       assert (instanceSize > 0 && instanceSize < 1000000);
  1990.  
  1991.       newODP = (LODataPtr) emallocnil(instanceSize);
  1992.       newODP->tag = t->TT.LO.tag;
  1993.       length = instanceSize - sizeof(ODTag);
  1994.       GETDATA(fHandlePtr, addOffset(newODP, sizeof(ODTag)), &length);
  1995.       assert(length == instanceSize - sizeof(ODTag));
  1996.  
  1997.       Set_Insert(fNewSet, (int) newODP);
  1998.  
  1999.       if (newODP->tag.replicated) {
  2000.     /* Check to see if we already know it */
  2001.     candidateODP = (RODataPtr) OTLookup(((RODataPtr) newODP)->ownOID);
  2002.     if (IsNULL(candidateODP)) {
  2003.       /* Do not know it; remember it now */
  2004.       OTInsert(((ODP) newODP));
  2005.       KMDTrace("TT", 4, "TT LO is replicated; first time here; OID %s\n",
  2006.            PPOID(((RODataPtr)newODP)->ownOID));
  2007.     } else {
  2008.       /* We already have a copy */
  2009.       KMDTrace("TT", 4, "TT LO is replicated; OID %s\n",
  2010.            PPOID(((RODataPtr)newODP)->ownOID));
  2011.       /* UNDO the new version and use the old one */
  2012.       Set_Delete(fNewSet, (int) newODP);
  2013.       emfree((char *)newODP);
  2014.       newODP = (LODataPtr) candidateODP;
  2015.     }
  2016.       }
  2017.       /* Insert the translation information into Translation Map */
  2018.       Map_Insert(fTMap, (int) t->TT.LO.oldODP, (int) newODP);
  2019.  
  2020.       KMDTrace("TT", 4, "TT LO size %d (0x%05x) -> (0x%05x)\n",
  2021.            instanceSize, t->TT.LO.oldODP, newODP);
  2022.       break;
  2023.     }
  2024.  
  2025.     case TTAbConITag: {
  2026.       /* Get rest of Entry */
  2027.       length = sizeof(TTAbConEntry) - sizeof(TTGenericEntry);
  2028.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)), &length);
  2029.       entry = (ODP) GetAbCon(t->TT.AB.ATOID, t->TT.AB.restrictOID,
  2030.                  t->TT.AB.CodeOID, t->TT.AB.tag);
  2031.       Map_Insert(fTMap, (int) t->TT.AB.oldODP, (int) entry);
  2032.       KMDTrace("TT", 4,
  2033.            "TT AT 0x%04x rAT 0x%04x CT 0x%04x %-9.9s (0x%05x)->(0x%05x)\n",
  2034.            t->TT.AB.ATOID, t->TT.AB.restrictOID, t->TT.AB.CodeOID,
  2035.            BasicTagName[(int) t->TT.AB.tag.tag],
  2036.            t->TT.AB.oldODP, entry);
  2037.       break;
  2038.     }
  2039.  
  2040.     case TTMoveGODITag: {
  2041.       int       instanceSize;
  2042.       GODataPtr theData;
  2043.  
  2044.       /* Get rest of GODEntry */
  2045.       length = sizeof(TTMoveGODEntry) - sizeof(TTGenericEntry);
  2046.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),    &length);
  2047.       entry = OTLookup(t->TT.MGOD.ownOID);
  2048.       if (IsNULL(entry)) {
  2049.     /* Insert a new entry */
  2050.     entry = getFreeOD();
  2051.     entry->G.ownOID     = t->TT.MGOD.ownOID;
  2052.     entry->G.tag        = t->TT.MGOD.tag;
  2053.     entry->G.tag.frozen = TRUE;
  2054.     entry->G.tag.isResident = TRUE;
  2055.     entry->G.tag.setUpDone = FALSE;
  2056.     entry->G.ownLoc     = NewLocation(t->TT.MGOD.ownLoc, GetLNN());
  2057.     entry->G.ARListHead.next = entry->G.ARListHead.prev =
  2058.       (InvokeQueuePtr) &entry->G.ARListHead;
  2059.     entry->G.myCodeOID  = t->TT.MGOD.myCodeOID;
  2060.     OTInsert(entry);
  2061.       } else {
  2062.     assert (entry->G.tag.tag == t->TT.MGOD.tag.tag);
  2063.     /* Check to see if location timestamp is newer */
  2064.     if (LOCATIONNEWER(t->TT.MGOD.ownLoc, entry->G.ownLoc)) {
  2065.       KMDTrace("TT", 3,
  2066.            "MoveGO OID 0x%05x was @ 0x%04x now @ 0x%04x\n",
  2067.            entry->G.ownOID, entry->G.ownLoc, t->TT.MGOD.ownLoc);
  2068.       entry->G.ownLoc = NewLocation(t->TT.MGOD.ownLoc,GetLNN());
  2069.       entry->G.tag.isResident = TRUE;
  2070.       entry->G.tag.frozen = !t->TT.MGOD.tag.setUpDone;
  2071.       KMDTrace("FixMe", 5,"Fix me: should reset ODTag flags properly.\n");
  2072.     }
  2073.       }
  2074.       /* Lookup and insert code, if necessary */
  2075.       codeEntry = (CodeODP) OTLookup(t->TT.MGOD.myCodeOID);
  2076.       if (IsNULL(codeEntry)) {    /* Create an entry */
  2077.     codeEntry = CreateCodeODEntry(t->TT.MGOD.myCodeOID, t->TT.MGOD.ownLoc);
  2078.       } else {            /* Verify that it is a code entry */
  2079.     assert(codeEntry->tag.tag == CodeODTag);
  2080.       }
  2081.       KMDTrace("TT", 4,
  2082.            "TTM 0x%04x %-9.9s@ 0x%04x (0x%05x)->(0x%05x) CT %s\n",
  2083.            t->TT.MGOD.ownOID, BasicTagName[(int) t->TT.MGOD.tag.tag],
  2084.            t->TT.MGOD.ownLoc, t->TT.MGOD.oldODP, entry,
  2085.            PPCOID(t->TT.MGOD.myCodeOID));
  2086.       entry->G.tag.setUpDone  = FALSE;
  2087.       entry->G.tag.frozen     = TRUE;
  2088.  
  2089.       /* Now get the data area */
  2090.       instanceSize = t->TT.MGOD.hdr.size - sizeof(TTMoveGODEntry);
  2091.       /* Hack: if there already is a data area, free it */
  2092.       if (NonNULL(entry->G.dataPtr) &&
  2093.       PPValidAddr((SSAddr *) entry->G.dataPtr) &&
  2094.       entry->G.dataPtr->tag.tag == GODataTag) {
  2095.     emfree((char *)entry->G.dataPtr);
  2096.       }
  2097.  
  2098.       entry->G.dataPtr = theData = (GODataPtr) emalloc(instanceSize);
  2099.       KMDTrace("FixMe", 4, "Consider whether tag should change\n");
  2100.       length = instanceSize;
  2101.       GETDATA(fHandlePtr, theData, &length);
  2102.       assert(length == instanceSize);
  2103.  
  2104.       if (!codeEntry->tag.setUpDone) {
  2105.     KMDTrace("TT", 4, "%s causing req for Code C%08x (old cPtr 0x%06x)\n",
  2106.          (isRecovery?"Recover":"Move"),
  2107.          codeEntry->ownOID, theData->myCodePtr);
  2108.     Map_Insert(fLoadMap, (int) codeEntry->ownOID, (int) theData->myCodePtr);
  2109.       } else {
  2110.     KMDTrace("TT", 4, "TT: (0x%06x -> 0x%06x) for codePtr %s\n",
  2111.          theData->myCodePtr, codeEntry->dataPtr,
  2112.          PPCodePtr(codeEntry->dataPtr));
  2113.     Map_Insert(fTMap, (int) theData->myCodePtr, (int) codeEntry->dataPtr);
  2114.       }
  2115.  
  2116.       /* Insert into translation map */
  2117.       Map_Insert(fTMap, (int) t->TT.MGOD.oldODP, (int) entry);
  2118.       Map_Insert(fTMap, (int) t->TT.MGOD.oldGODataPtr, (int) theData);
  2119.  
  2120.       /* Insert object into map of newly arrived objects */
  2121.       Set_Insert(fNewSet, (int) entry);
  2122.  
  2123.       KMDTrace((isRecovery?"Recover":"Move"), 3, "Object %s %s here.\n",
  2124.            PPGOID(entry->G.ownOID), (isRecovery?"recovered":"moved to"));
  2125.       break;
  2126.     }
  2127.  
  2128.     case TTMoveCITag: {
  2129.       register CodeODP        theCodeODP;
  2130.       /* Get rest of entry */
  2131.       length = sizeof(TTMoveCEntry) - sizeof(TTGenericEntry);
  2132.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),&length);
  2133.       assert (length == sizeof(TTMoveCEntry) - sizeof(TTGenericEntry));
  2134.       theCodeODP = (CodeODP) OTLookup(t->TT.MC.ownOID);
  2135.       if (IsNULL(theCodeODP)) {
  2136.     /* Create an entry for some unknown code object */
  2137.     theCodeODP = CreateCodeODEntry(t->TT.MC.ownOID, t->TT.MC.ownLoc);
  2138.       }
  2139.       if (!theCodeODP->tag.setUpDone) {
  2140.     /* We need to load it so put it into the load map */
  2141.     KMDTrace("TT", 4, "TT: MoveC: Req for Code C%08x (old cPtr 0x%06x)\n",
  2142.          t->TT.MC.ownOID, t->TT.MC.oldODP);
  2143.     Map_Insert(fLoadMap, (int) t->TT.MC.ownOID, (int) t->TT.MC.oldODP);
  2144.       } else {
  2145.     theCodeODP->ownLoc = t->TT.MC.ownLoc;
  2146.     KMDTrace("TT", 4, "TT: MoveC: (0x%06x -> 0x%06x) codePtr for %s\n",
  2147.          t->TT.MC.oldODP, theCodeODP->dataPtr,
  2148.          PPCOID(theCodeODP->ownOID));
  2149.     Map_Insert(fTMap, (int) t->TT.MC.oldODP, (int) theCodeODP->dataPtr);
  2150.       }
  2151.       break;
  2152.     }
  2153.  
  2154.     case TTCodeAddrITag: {
  2155.       if(isRecovery){
  2156.     ErrMsg("RecoverDigestTable: TTCodeAddrITag in recovered object?");
  2157.     abort();
  2158.       } else {
  2159.     OID      theOID;
  2160.     Offset   theOffset;
  2161.     CodeAddr newAddr;
  2162.     CodeODP  theCodeODP;
  2163.     TRecPtr  tRec;
  2164.  
  2165.  
  2166.     /* Get rest of entry */
  2167.     length = sizeof(TTCodeAddrEntry) - sizeof(TTGenericEntry);
  2168.     LMGetData(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),&length);
  2169.     assert (length == sizeof(TTCodeAddrEntry)-sizeof(TTGenericEntry));
  2170.  
  2171.     /* Forget it, if  it is already there */
  2172.     if (NonNIL(Map_Lookup(fTMap, (int) t->TT.CA.oldODP))) break;
  2173.  
  2174.     theOID = t->TT.CA.theCodeOID;
  2175.     theOffset = t->TT.CA.theOffset;
  2176.     if (IsNULL(theOID)) {
  2177.       /* It is an address of a return-to-kernel routine */
  2178.       newAddr = (CodeAddr) Map_Lookup(KernelReturnOpNumberMap, (int) theOffset);
  2179.       KMDTrace("TT", 4, "TT: Kernel addr 0x%06x -> 0x%06x op #%d\n",
  2180.            t->TT.CA.oldODP, newAddr, theOffset);
  2181.       Map_Insert(fTMap, (int) t->TT.CA.oldODP, (int) newAddr);
  2182.     } else {
  2183.       /* It is an address in Emerald code */
  2184.       theCodeODP  = (CodeODP) OTLookup(theOID);
  2185.       if (IsNULL(theCodeODP) || IsNULL(theCodeODP->dataPtr)) {
  2186.         /* Rats, we do not have the code -- delay the translation. */
  2187.         if (IsNULL(theCodeODP)) {
  2188.           /* Create one */
  2189.           theCodeODP =
  2190.         CreateCodeODEntry
  2191.           (theOID, mMakeLocation((*fHandlePtr)->mmMsgHdr.MsgSrc,1));
  2192.         }
  2193.  
  2194.         /*
  2195.          * Note: no load request for the code since one is
  2196.          * generated by the moved object.
  2197.          * 
  2198.          * Put a translation record into the map.
  2199.          */
  2200.  
  2201.         KMDTrace("TT", 4,
  2202.              "TT: TRec for code addr 0x%08x, OID %s, offset %d\n", 
  2203.              t->TT.CA.oldODP, PPCOID(theOID), theOffset);
  2204.         tRec = (TRecPtr) malloc(sizeof(TRec));
  2205.         tRec->theOID        = theOID;
  2206.         tRec->theOffset     = theOffset;
  2207.         /*
  2208.          * The fact that we do not have the address is
  2209.          * indicated by inserting the record pointer negated.
  2210.          * (OK, so it is a hack).
  2211.          */
  2212.         Map_Insert(fTMap, (int) t->TT.CA.oldODP,  - (int) tRec);
  2213.         break;
  2214.       }
  2215.       newAddr     = (CodeAddr) addOffset(theCodeODP->dataPtr, theOffset);
  2216.       KMDTrace("TT", 4, "TT: Code Addr 0x%06x -> 0x%06x offset %d in %s\n",
  2217.            t->TT.CA.oldODP, newAddr, theOffset,
  2218.            PPCodePtr(theCodeODP->dataPtr));
  2219.       Map_Insert(fTMap, (int) t->TT.CA.oldODP, (int) newAddr);
  2220.     }
  2221.     break;
  2222.       }
  2223.     }
  2224.  
  2225.     case TTMoveSSODITag: {
  2226.       if(isRecovery){
  2227.     ErrMsg("Should never get a TTMoveSSODITag in RecoverDigestTable #2!");
  2228.     abort();
  2229.       } else {
  2230.     register TTMoveSSODEntry   *s;
  2231.     SSODP                       theSSODP;
  2232.     SSPtr                       p;
  2233.     int                         sizeOfStack;
  2234.     Offset                      delta;
  2235.     SSAddr                      newAddr;
  2236.  
  2237.     /*
  2238.      * Read rest of SSOD info
  2239.      * Allocate and fill in SSOD and SS
  2240.      * read in stack
  2241.      * insert stack info
  2242.      */
  2243.     length = sizeof(TTMoveSSODEntry) - sizeof(TTGenericEntry);
  2244.     LMGetData(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)), &length);
  2245.     s               = &t->TT.MSS;
  2246.     theSSODP        = (SSODP) OTLookup(s->ownOID);
  2247.     if (IsNULL(theSSODP)) {
  2248.       p                   = NewStackSegment(s->thisSegmentSize);
  2249.       theSSODP            = p->ownSSODP;
  2250.       theSSODP->ownOID    = s->ownOID;
  2251.       theSSODP->ownLoc    = NewLocation(s->ownLoc, GetLNN());
  2252.       theSSODP->processOID= s->processOID;
  2253.       theSSODP->tag.isResident = TRUE;
  2254.       OTInsert((ODP) theSSODP);
  2255.     } else {
  2256.       SSODP               newSSODP;
  2257.       EmLocation          theNewLocation;
  2258.       NodeNum             myLNN = GetLNN();
  2259.  
  2260.       theNewLocation      = NewLocation(s->ownLoc, myLNN);
  2261.       UpdateLocation(s->ownOID, theNewLocation, myLNN);
  2262.  
  2263.       /* 
  2264.        * Boy is this dumb, we already have an OD and have to
  2265.        * discard the new one.
  2266.        */
  2267.       KMDTrace("FixMe", 5, "FixMe: use better OD alloc in DigestSSOD\n");
  2268.       p                 = NewStackSegment(s->thisSegmentSize);
  2269.       newSSODP          = p->ownSSODP;
  2270.       theSSODP->dataPtr = p;
  2271.       p->ownSSODP       = theSSODP;
  2272.       emfree((char *)newSSODP);
  2273.     }
  2274.     /* assert(theSSODP points to an SS of appropriate size) */
  2275.     theSSODP->tag.isResident= TRUE;
  2276.     theSSODP->tag.frozen    = TRUE;
  2277.     p->availStack   = s->availStack;
  2278.     p->processOID   = s->processOID;
  2279.     p->ownOID       = s->ownOID;
  2280.     p->regs         = s->regs;
  2281.     p->resultBrand  = s->resultBrand;
  2282.     p->readyQLink   = s->oldReadyQLink;
  2283.     p->rPtr         = s->rPtr;
  2284.     p->invokePtr    = s->invokePtr;
  2285.     p->status       = s->status;
  2286.     KMDTrace("Move", 3,
  2287.          "Stack Segment %s moved here, Process %s status %s\n",
  2288.          PPOID(p->ownOID), PPPOID(p->processOID),
  2289.          PPSSRunStatus((int)p->status.rs));
  2290.     /*
  2291.      * The rest of the item is a variable sized stack area.
  2292.      * Compute size and relocation addressing.
  2293.      */
  2294.     sizeOfStack     = t->TT.MSS.hdr.size - sizeof(TTMoveSSODEntry);
  2295.     KMDTrace("FixMe", 4, "(FixMe: PORTABILITY:Stacks grow high->low\n)");
  2296.     /* PORTABILITY:
  2297.      * Stacks grow from high addresses toward low addresses.
  2298.      */
  2299.  
  2300.     /* Offset from high end of area since stacks grow down */
  2301.     newAddr         = (SSAddr) addOffset(p->endOfSS, -sizeOfStack);
  2302.     delta           = (Offset) byteOffset(s->oldSSPtr, newAddr);
  2303.  
  2304.     KMDTrace("Move", 5, "SS old SSPtr 0x%06x newSS 0x%06x delta 0x%06x\n",
  2305.          s->oldSSPtr, p, delta);
  2306.     KMDTrace("Move", 5, "sp 0x%06x -> 0x%06x size %d endOfSS 0x%06x\n",
  2307.          s->regs.sp, newAddr, sizeOfStack, p->endOfSS);
  2308.  
  2309.     length = sizeOfStack;
  2310.     LMGetData(fHandlePtr, newAddr, &length);
  2311.     assert(length == sizeOfStack);
  2312.  
  2313.     /* Insert SS and its current sp into translation map */
  2314.     Map_Insert(fTMap, (int) s->oldSSPtr, (int) p);
  2315.     Map_Insert(fTMap, (int) p->regs.sp, (int) newAddr);
  2316.  
  2317.     /* Insert SS into map of newly arrived objects */
  2318.     Set_Insert(fNewSet, (int) p);
  2319.  
  2320.     break;
  2321.       }
  2322.     }
  2323.  
  2324.     case TTInvokeITag: {
  2325.       register InvokeReqPtr       req;
  2326.       length  = sizeof(TTInvokeReqEntry) - sizeof(TTGenericEntry);
  2327.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),&length);
  2328.       assert (length==sizeof(TTInvokeReqEntry)-sizeof(TTGenericEntry));
  2329.       req                     = mNewRequest(Invoke);
  2330.       req->i.callerSSOID      = t->TT.IR.callerSSOID;
  2331.       req->i.callerLoc        = t->TT.IR.callerLoc;
  2332.       req->i.argumentCount    = t->TT.IR.argumentCount;
  2333.       req->i.resultCount      = t->TT.IR.resultCount;
  2334.       req->i.processOID       = t->TT.IR.processOID;
  2335.       req->i.targetOID        = t->TT.IR.targetOID;
  2336.       req->i.targetTryAtLoc   = t->TT.IR.targetTryAtLoc;
  2337.       req->m                  = (Map) NULL;
  2338.       req->neededMap          = (Map) NULL;
  2339.       req->newSet             = (Set) NULL;
  2340.  
  2341.       Map_Insert(fTMap, (int) t->TT.IR.oldODP, (int) req);
  2342.  
  2343.       /* Note, that req get translated when the SS that they are req for
  2344.        * are translated and thus reqs are NOT entered into the fNewSet
  2345.        * (they could not be in it anyway since they do not have ODTags)
  2346.        */
  2347.       KMDTrace("TT", 4, "TT: InvokeReq %s target %s\n",
  2348.            PPPOID(req->i.processOID), PPGOID(req->i.targetOID));
  2349.       KMDTrace("TT", 5, "    %d arg%s %d result%s\n",
  2350.            req->i.argumentCount, mPLURAL(req->i.argumentCount),
  2351.            req->i.resultCount, mPLURAL(req->i.resultCount));
  2352.       break;
  2353.     }
  2354.  
  2355.     case TTIncomingIITag: {
  2356.       register IncomingIReqPtr        req;
  2357.       length  = sizeof(TTIncomingIReqEntry) - sizeof(TTGenericEntry);
  2358.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),&length);
  2359.       assert(length==sizeof(TTIncomingIReqEntry)-sizeof(TTGenericEntry));
  2360.       req                     = mNewRequest(IncomingI);
  2361.       req->status             = IHCodeLoadDone;
  2362.       req->i.callerSSOID      = t->TT.IIR.callerSSOID;
  2363.       req->i.callerLoc        = t->TT.IIR.callerLoc;
  2364.       req->i.argumentCount    = t->TT.IIR.argumentCount;
  2365.       req->i.resultCount      = t->TT.IIR.resultCount;
  2366.       req->i.processOID       = t->TT.IIR.processOID;
  2367.       req->i.targetOID        = t->TT.IIR.targetOID;
  2368.       req->i.targetTryAtLoc   = t->TT.IIR.targetTryAtLoc;
  2369.       req->i.stackAvailable   = NIL;
  2370.                     
  2371.       req->opNumber           = -1;
  2372.       req->visitorSet         = (Set) NULL;
  2373.  
  2374.       Map_Insert(fTMap, (int) t->TT.IIR.oldODP, (int) req);
  2375.  
  2376.       /* Note, that req get translated when the SS that they are req for
  2377.        * are translated and thus reqs are NOT entered into the fNewSet
  2378.        * (they could not be in it anyway since they do not have ODTags)
  2379.        */
  2380.       KMDTrace("TT", 4, "TT: IncomingIReq %s target %s\n",
  2381.            PPPOID(req->i.processOID), PPGOID(req->i.targetOID));
  2382.       KMDTrace("TT", 5, "    %d arg%s %d result%s\n",
  2383.            req->i.argumentCount, mPLURAL(req->i.argumentCount),
  2384.            req->i.resultCount, mPLURAL(req->i.resultCount));
  2385.       break;
  2386.     }
  2387.  
  2388.     case TTCondITag: {
  2389.       /* Get rest of CondEntry */
  2390.       length = sizeof(TTCondEntry) - sizeof(TTGenericEntry);
  2391.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),    &length);
  2392.       entry = OTLookup(t->TT.CD.ownOID);
  2393.       if (IsNULL(entry)) {
  2394.     /* Insert a new entry */
  2395.     entry = getFreeOD();
  2396.     entry->CD.ownOID     = t->TT.CD.ownOID;
  2397.     entry->CD.tag        = t->TT.CD.tag;
  2398.     entry->CD.tag.frozen = TRUE;
  2399.     entry->CD.tag.isResident = FALSE;
  2400.     entry->CD.ownLoc     = t->TT.CD.ownLoc;
  2401.     entry->CD.theLock    = (MonitorLockPtr) EMNIL;
  2402.     entry->CD.ARListHead.next = entry->CD.ARListHead.prev =
  2403.       (InvokeQueuePtr) &entry->CD.ARListHead;
  2404.     entry->CD.waiting   = (SSPtr) NULL;
  2405.     OTInsert(entry);
  2406.       } else {
  2407.     assert (entry->CD.tag.tag == t->TT.CD.tag.tag);
  2408.     /* Check to see if location timestamp is newer */
  2409.     if (entry->G.ownLoc < t->TT.FGOD.ownLoc) {
  2410.       KMDTrace("TT", 3, "Cond OID %s was @ 0x%04x now @ 0x%04x\n",
  2411.            PPOID(entry->CD.ownOID), entry->CD.ownLoc, t->TT.CD.ownLoc);
  2412.       entry->CD.ownLoc = t->TT.CD.ownLoc;
  2413.       KMDTrace("FixMe", 5, "Fix me: should reset ODTag flags.\n");
  2414.     }
  2415.       }
  2416.       Map_Insert(fTMap, (int) t->TT.CD.oldODP, (int) entry);
  2417.       KMDTrace("TT", 4, "TT Cond %s %-9.9s@%s (0x%05x -> 0x%05x)\n",
  2418.            PPOID(t->TT.CD.ownOID), PPODBasicTag(t->TT.CD.tag.tag),
  2419.            PPLoc(t->TT.CD.ownLoc), t->TT.CD.oldODP, entry);
  2420.       break;
  2421.     }
  2422.  
  2423.     case TTFetchGODITag: {
  2424.       /* Get rest of FetchGODEntry */
  2425.       length = sizeof(TTFetchGODEntry) - sizeof(TTGenericEntry);
  2426.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),&length);
  2427.       entry = OTLookup(t->TT.FGOD.ownOID);
  2428.       if (IsNULL(entry)) {
  2429.     /* Insert a new entry */
  2430.     entry             = getFreeOD();
  2431.     entry->G.ownOID     = t->TT.FGOD.ownOID;
  2432.     entry->G.tag        = t->TT.FGOD.tag;
  2433.     entry->G.tag.frozen = TRUE;
  2434.     entry->G.tag.isResident = FALSE;
  2435.     entry->G.ownLoc     = t->TT.FGOD.ownLoc;
  2436.     entry->G.ARListHead.next = entry->G.ARListHead.prev =
  2437.       (InvokeQueuePtr) &entry->G.ARListHead;
  2438.     entry->G.myCodeOID  = t->TT.FGOD.myCodeOID;
  2439.     /* Lookup and insert code, if necessary */
  2440.     codeEntry = (CodeODP) OTLookup(t->TT.FGOD.myCodeOID);
  2441.     if (IsNULL(codeEntry)) {    /* Create an entry */
  2442.       codeEntry= CreateCodeODEntry(t->TT.FGOD.myCodeOID,t->TT.FGOD.ownLoc);
  2443.     } else {            /* Verify that it is a code entry */
  2444.       assert(codeEntry->tag.tag == CodeODTag);
  2445.     }
  2446.     OTInsert(entry);
  2447.       } else {
  2448.     assert (entry->G.tag.tag == t->TT.FGOD.tag.tag);
  2449.     /* Check to see if location timestamp is newer */
  2450.     if (LOCATIONNEWER(t->TT.FGOD.ownLoc, entry->G.ownLoc)) {
  2451.       KMDTrace("TT", 3, "GO OID 0x%05x was @ 0x%04x now @ 0x%04x\n",
  2452.            entry->G.ownOID, entry->G.ownLoc, t->TT.FGOD.ownLoc);
  2453.       entry->G.ownLoc = t->TT.FGOD.ownLoc;
  2454.       KMDTrace("FixMe", 5, "Fix me: should reset ODTag flags.\n");
  2455.     }
  2456.       }
  2457.       Map_Insert(fTMap, (int) t->TT.FGOD.oldODP, (int) entry);
  2458.       KMDTrace("TT", 4,
  2459.            "TTFetchGOD %#04x %-9.9s@0x%04x (0x%05x)->(0x%05x) CT 0x%05x\n",
  2460.            t->TT.FGOD.ownOID, BasicTagName[(int) t->TT.FGOD.tag.tag],
  2461.            t->TT.FGOD.ownLoc, t->TT.FGOD.oldODP, entry,
  2462.            t->TT.FGOD.myCodeOID);
  2463.       break;
  2464.     }
  2465.  
  2466.     case TTMoveCondITag: {
  2467.       register CondODP        theCondODP;
  2468.       /* Get rest of entry */
  2469.       length = sizeof(TTMoveCondEntry) - sizeof(TTGenericEntry);
  2470.       GETDATA(fHandlePtr, addOffset(t, sizeof(TTGenericEntry)),&length);
  2471.       assert(length == sizeof(TTMoveCondEntry)-sizeof(TTGenericEntry));
  2472.       theCondODP = (CondODP) OTLookup(t->TT.MCD.ownOID);
  2473.       if (IsNULL(theCondODP)) {
  2474.     /* Insert a new entry */
  2475.     theCondODP              = (CondODP) getFreeOD();
  2476.     theCondODP->ownOID      = t->TT.MCD.ownOID;
  2477.     theCondODP->tag         = t->TT.MCD.tag;
  2478.     theCondODP->ownLoc      = t->TT.MCD.ownLoc;
  2479.     theCondODP->ARListHead.next = theCondODP->ARListHead.prev =
  2480.       (InvokeQueuePtr) &theCondODP->ARListHead;
  2481.     theCondODP->dataPtr     = (GODataPtr) NULL;
  2482.     OTInsert((ODP) theCondODP);
  2483.       }
  2484.       theCondODP->tag.isResident  = TRUE;
  2485.       theCondODP->tag.frozen      = TRUE;
  2486.       theCondODP->theLock         = t->TT.MCD.theLock;
  2487.       theCondODP->waiting         = (isRecovery?NULL:t->TT.MCD.theWaiting);
  2488.       theCondODP->ownLoc          = NewLocation(theCondODP->ownLoc,GetLNN());
  2489.  
  2490.       /*
  2491.        * Insert into translation map.
  2492.        */
  2493.       Map_Insert(fTMap, (int) t->TT.MCD.oldODP, (int) theCondODP);
  2494.  
  2495.       /*
  2496.        * Insert into map of arrived objects that need translating.
  2497.        */
  2498.       Set_Insert(fNewSet, (int) theCondODP);
  2499.  
  2500.       KMDTrace("TT", 4, "TT: MoveCond (0x%06x -> 0x%06x) %s\n",
  2501.            t->TT.MCD.oldODP, theCondODP, PPOID(theCondODP->ownOID));
  2502.  
  2503.       KMDTrace((isRecovery?"Recover":"Move"), 3,
  2504.            "Condition (%s) moved here (%s)\n",
  2505.            PPOID(theCondODP->ownOID), PPLoc(theCondODP->ownLoc));
  2506.       break;
  2507.     }
  2508.  
  2509.     default: {
  2510.       ErrMsg("Cannot Digest item tag %s\n", PPITag(t->TT.GO.hdr.itemTag));
  2511.       abort();
  2512.     }
  2513.     }
  2514.  
  2515.     /* Get the Item hdr and the OD tag of the next translate item. */
  2516.     length  = sizeof(TTGenericEntry);
  2517.     GETDATA(fHandlePtr, t, &length);
  2518.   }
  2519.     
  2520.   /*
  2521.    * The TTable information has now been digested.  The loop
  2522.    * terminated either because there was no more data or because
  2523.    * a different item was found in which case the position must be
  2524.    * moved back.
  2525.    */
  2526.  
  2527.   if (length > 0) {
  2528.     /* Reset position so the other item may be reread */
  2529.     SEEKDATA(fHandlePtr, (long) -length, (long) 1);
  2530.   }
  2531. }
  2532.  
  2533.  
  2534.  
  2535. /*
  2536.  * TranslateReq
  2537.  *
  2538.  * Translate the given request data structure using the fTMap;
  2539.  * the reference itself is also translated and returned.
  2540.  * If a SS is associated with the Req then the fSSPtr given is
  2541.  * used to set the appropriate field.
  2542.  */
  2543. GenericReqPtr TranslateReq(fReq, fTMap, fSSPtr)
  2544. GenericReqPtr fReq;
  2545. Map   fTMap;
  2546. SSPtr fSSPtr;
  2547. {
  2548.   GenericReqPtr newReq;
  2549.  
  2550.   newReq = (GenericReqPtr) Map_Lookup(fTMap, (int) fReq);
  2551.     
  2552.   KMDTrace("TT", 3, "Translating Request (0x%06x -> 0x%06x) %s\n",
  2553.        fReq, newReq, PPRTag(newReq->hdr.rTag));
  2554.  
  2555.   switch (newReq->hdr.rTag) {
  2556.  
  2557.   case InvokeRTag: {
  2558.     register InvokeReqPtr   req = (InvokeReqPtr) newReq;
  2559.  
  2560.     req->requestor  = fSSPtr;
  2561.     req->targetGODP = (GODP) OTLookup(req->i.targetOID);
  2562.     assert(NonNULL(req->targetGODP));
  2563.     req->theAbConPtr= (AbConPtr) NULL;  /* Irrelevant */
  2564.     break;
  2565.   }
  2566.  
  2567.   case IncomingIRTag: {
  2568.     register IncomingIReqPtr req = (IncomingIReqPtr) newReq;
  2569.     req->theProcess     = fSSPtr;
  2570.     break;
  2571.   }
  2572.   }
  2573.   return newReq;
  2574. }
  2575.  
  2576.  
  2577.  
  2578. /*
  2579.  * TranslateCodeAddr
  2580.  */
  2581. CodeAddr TranslateCodeAddr(fTMap, fOldAddr)
  2582. Map      fTMap;
  2583. CodeAddr fOldAddr;
  2584. {
  2585.   CodeAddr newAddr;
  2586.   CodeODP  theCodeODP;
  2587.   TRecPtr  theTRec;
  2588.     
  2589.   newAddr = (CodeAddr) Map_Lookup(fTMap, (int) fOldAddr);
  2590.   if (IsNIL(newAddr)) {
  2591.     ErrMsg("Translation error, addr 0x%08x unknown\n", newAddr);
  2592.     abort();
  2593.   }
  2594.   if (( (int) newAddr) < 0) {
  2595.     /* The code was not loaded when the address arrived but it should be
  2596.      * here now.
  2597.      */
  2598.     theTRec = (TRecPtr) (- ((int) newAddr)); /* HACK */
  2599.     theCodeODP = (CodeODP) OTLookup(theTRec->theOID);
  2600.     assert(NonNULL(theCodeODP));
  2601.     newAddr = (CodeAddr) addOffset(theCodeODP->dataPtr, theTRec->theOffset);
  2602.     KMDTrace("TT", 3,
  2603.          "TT: redo codeaddr (0x%06x -> 0x%06x) offset %d in %s, line %s\n",
  2604.          fOldAddr, newAddr, theTRec->theOffset,
  2605.          PPCodePtr(theCodeODP->dataPtr),
  2606.          PPFindLineNo(theCodeODP->dataPtr, newAddr));
  2607.     Map_Insert(fTMap, (int) fOldAddr, (int) newAddr);
  2608.     free((char *)theTRec);
  2609.   }
  2610.  
  2611.   KMDTrace("TT", 4, "TT: code addr (0x%06x -> 0x%06x)\n", fOldAddr, newAddr);
  2612.   return newAddr;
  2613. }
  2614.  
  2615. /************************************************************************/
  2616. /************************************************************************/
  2617.  
  2618. /*
  2619.  * ShoutOrSearchTimeOut
  2620.  */
  2621. void ShoutOrSearchTimeOut(fOID, fTimerId, whichOne)
  2622. OID  fOID;
  2623. int  fTimerId;
  2624. LocateStatus whichOne;
  2625. {
  2626.   register LocateReqPtr   req;
  2627.  
  2628.   KMDTrace("Locate", 4, (whichOne==Shouting ? "Shout" : "Search"));
  2629.   KMDTrace("Locate", 4, "TimeOut for %s; start searching\n", PPOID(fOID));
  2630.   req = (LocateReqPtr) Map_Lookup(LocateMap, (int) fOID);
  2631.   if (IsNIL(req)) {
  2632.     KMDTrace("Locate",4,
  2633.          whichOne == Shouting ?
  2634.          "ShoutTimeOut: %s - request already gone\n" :
  2635.          "SearchTimeOut: %s has already been found.\n",
  2636.          PPOID(fOID));
  2637.     return;
  2638.   }
  2639.   if (req->timerId != fTimerId) {
  2640.     KMDTrace("Locate", 4,
  2641.          whichOne == Shouting ?
  2642.          "ShoutTimeOut for %s - request long gone\n":
  2643.          "Already done (new req found).\n",
  2644.          PPOID(fOID));
  2645.   }
  2646.   if (req->status == Shouting) {
  2647.     KMDTrace("Locate", 3, "%s: try searching\n", PPOID(fOID));
  2648.     StartSearching(req);
  2649.   } else if(req->status == Searching){
  2650.     /*
  2651.      * One or more nodes has not responded to a search broadcast --
  2652.      * prod them using point to point messages.
  2653.      */
  2654.     KMDTrace("Loacte", 3, "Prodding nodes\n");
  2655.     CheckForProd(req);
  2656.   }
  2657. }
  2658.  
  2659. HResult ShoutTimeOut(fOID, fTimerId)
  2660. OID  fOID;
  2661. int  fTimerId;
  2662. {
  2663.   ShoutOrSearchTimeOut(fOID, fTimerId, Shouting);
  2664. }
  2665.  
  2666. HResult SearchTimeOut(fOID, fTimerId)
  2667. OID  fOID;
  2668. int  fTimerId;
  2669. {
  2670.   ShoutOrSearchTimeOut(fOID, fTimerId, Searching);
  2671. }
  2672.  
  2673.  
  2674.  
  2675. /*
  2676.  * LocationDeamon
  2677.  *
  2678.  * Scheduled to run when there are outstanding shout or search requests
  2679.  * Does the actual sending of location requests
  2680.  */
  2681. HResult LocationDeamon()
  2682. {
  2683.   LMHandle     myHandle;
  2684.   LocateItem   item;
  2685.   LocateInfo   info;
  2686.   register int i;
  2687.  
  2688.   KMDTrace("Locate", 4, "Locate Deamon activated\n");
  2689.  
  2690.   if (searchList->count > 0) {
  2691.     /* Work to do */
  2692.     KMDTrace("Locate", 3, "Locate Deamon broadcast search for %d object\n",
  2693.          searchList->count);
  2694.     LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, NULL);
  2695.  
  2696.     /* Put stuff into the msg */
  2697.     item.hdr.itemTag = SearchITag;
  2698.     item.hdr.size    = searchList->count * sizeof(info) + sizeof(item.hdr);
  2699.     LMPutData(&myHandle, &item, sizeof(item.hdr));
  2700.  
  2701.     KMDTrace("FixMe", 4, "Search list: Fix handling of overflow\n");
  2702.     assert(searchList->count < 200);
  2703.     for (i = 0; i < searchList->count; i++) {
  2704.       info.theOID = (OID) searchList->array[i];
  2705.       info.theLocation = (EmLocation) NULL;
  2706.       LMPutData(&myHandle, &info, sizeof(info));
  2707.     }
  2708.     cLOC_SearchsSent += searchList->count;
  2709.     cLOC_SearchBroadcastsSent++;
  2710.  
  2711.     (void) LMBroadcastMsg(&myHandle);
  2712.     DynClear(searchList);
  2713.   }
  2714.  
  2715.   if (shoutList->count > 0) {
  2716.     /* Work to do */
  2717.     KMDTrace("Locate", 3, "Locate Deamon broadcast shout for %d object\n",
  2718.          shoutList->count);
  2719.     LMStartMsg(&myHandle, KMSG_EmKernel, EMKM_Item, NULL);
  2720.  
  2721.     /* Put stuff into the msg */
  2722.     item.hdr.itemTag = ShoutITag;
  2723.     item.hdr.size    = shoutList->count * sizeof(info) + sizeof(item.hdr);
  2724.     LMPutData(&myHandle, &item, sizeof(item.hdr));
  2725.  
  2726.     KMDTrace("FixMe", 3, "Search list overflow is not handled\n");
  2727.     assert(shoutList->count < 200);
  2728.     for (i = 0; i < shoutList->count; i++) {
  2729.       info.theOID = (OID) shoutList->array[i];
  2730.       info.theLocation = (EmLocation) NULL;
  2731.       LMPutData(&myHandle, &info, sizeof(info));
  2732.     }
  2733.     cLOC_ShoutsSent +=    shoutList->count;
  2734.     cLOC_ShoutBroadcastsSent++;
  2735.  
  2736.     (void) LMBroadcastMsg(&myHandle);
  2737.     DynClear(shoutList);
  2738.   }
  2739.   LocationDeamonRunning = FALSE;
  2740. }
  2741.  
  2742.  
  2743. /*
  2744.  * Schedule the Locate Deamon if it is not already running
  2745.  */
  2746. void EnsureLocationDeamon()
  2747. {
  2748.   if (!LocationDeamonRunning) {
  2749.     KMDTrace("Locate", 5, "Scheduling Location Deamon\n");
  2750.     LocationDeamonRunning = TRUE;
  2751.     (void) MMSetMicroTimer((int)(vLOCDeamonInterval/1000000),
  2752.                (int)(vLOCDeamonInterval % 1000000),
  2753.                (HandlerPtr)LocationDeamon, NULL, (TimerId *)NULL);
  2754.   }
  2755. }
  2756.  
  2757. /************************************************************************/
  2758. /************************************************************************/
  2759.  
  2760. void LocateInit()
  2761. {
  2762.   int bits, i, theAddr, theOpNumber;
  2763.  
  2764.   KMDTrace("FixMe", 5, "Consider checking result of LMBroadcastMsg\n");
  2765.  
  2766.   KMDSetTrace(OT);
  2767.   KMDSetTrace(TT);
  2768.   KMDSetTrace(Locate);
  2769.  
  2770.   KMDTrace("Locate", 4, "LocateInit, initial OT size %d\n", INITIALOTSIZE);
  2771.   KMDTrace("OT", 4, "LocateInit, initial OT size %d\n", INITIALOTSIZE);
  2772.  
  2773.   KMDSetSnap(OTDump);
  2774.   KMDSetSnap(OTDataDump);
  2775.   KMDSetSnap(LOCLocateMap);
  2776.   KMDSetSnap(EmDataDump);
  2777.   KMDSetSnap(EmCTRefDump);
  2778.  
  2779.   /* Allocate Object table */
  2780.   OTSize = INITIALOTSIZE;
  2781.   OTMask = OTSize - 1;
  2782.   /* Check for OTSize power of 2 by counting bits */
  2783.   for (bits = 0, i = OTSize; i != 0 ; i >>= 1) if (i & 01) bits++;
  2784.   if (bits != 1) {
  2785.     ErrMsg("Error: Hash table size not power of 2 ***\n");
  2786.     ErrMsg("    Was %d\n", OTSize);
  2787.     for (bits = 0, i = OTSize; i != 0 ; i>>=1, bits++);
  2788.     OTSize = 1 <<   bits;
  2789.     ErrMsg("    Changed to %d\n", OTSize);
  2790.     OTMask = OTSize -1;
  2791.   }
  2792.   OTLimit = OTSize - (OTSize >> 3) - 1;  /* Fill no more than 87.5% */
  2793.   CreateArray((int **)&OT, OTSize * sizeof(ODP));
  2794.   KMDTrace("FixMe", 5, "The following assumes that NULL is 0\n");
  2795.   assert(NULL == 0);
  2796.   bzero((char *) (&OT[0]), OTSize * sizeof(ODP));
  2797.   nOT = 0;
  2798.  
  2799.   /* Preinitialize structures for AddToTTable */
  2800.   godEntry.hdr.itemTag        = TTGODITag;
  2801.   godEntry.hdr.size           = sizeof(godEntry);
  2802.   condEntry.hdr.itemTag       = TTCondITag;
  2803.   condEntry.hdr.size          = sizeof(condEntry);
  2804.   ssodEntry.hdr.itemTag       = TTSSODITag;
  2805.   ssodEntry.hdr.size          = sizeof(ssodEntry);
  2806.   abconEntry.hdr.itemTag      = TTAbConITag;
  2807.   abconEntry.hdr.size         = sizeof(abconEntry);
  2808.   codeodEntry.hdr.itemTag     = TTCodeODITag;
  2809.   codeodEntry.hdr.size        = sizeof(codeodEntry);
  2810.   loEntry.hdr.itemTag         = TTLOITag;
  2811.   loEntry.hdr.size            = sizeof(loEntry);
  2812.   movegodEntry.hdr.itemTag    = TTMoveGODITag;
  2813.   movegodEntry.hdr.size       = sizeof(movegodEntry);
  2814.   movecodeodEntry.hdr.itemTag = TTMoveCITag;
  2815.   movecodeodEntry.hdr.size    = sizeof(movecodeodEntry);
  2816.   fetchgodEntry.hdr.itemTag   = TTFetchGODITag;
  2817.   fetchgodEntry.hdr.size      = sizeof(fetchgodEntry);
  2818.   codeaddrEntry.hdr.itemTag   = TTCodeAddrITag;
  2819.   codeaddrEntry.hdr.size      = sizeof(codeaddrEntry);
  2820.   moveCondEntry.hdr.itemTag   = TTMoveCondITag;
  2821.   moveCondEntry.hdr.size      = sizeof(TTMoveCondEntry);
  2822.  
  2823.   SetItemHandler(ConfirmITag, ConfirmItemHandler);
  2824.   SetItemHandler(ShoutITag, ShoutItemHandler);
  2825.   SetItemHandler(SearchITag, SearchItemHandler);
  2826.   SetItemHandler(ConfirmReplyITag, ConfirmReplyItemHandler);
  2827.   SetItemHandler(ShoutReplyITag, ShoutReplyItemHandler);
  2828.   SetItemHandler(SearchReplyITag, SearchReplyItemHandler);
  2829.  
  2830.   LocateMap = Map_Create();
  2831.   KernelReturnAddressMap = Map_Create();
  2832.   Map_Insert(KernelReturnAddressMap, (int) &ReturnOffStack, 1);
  2833.  
  2834.   /* Now invert the KernelReturnAddressMap */
  2835.   KernelReturnOpNumberMap = Map_Create();
  2836.   Map_For(KernelReturnAddressMap, theAddr, theOpNumber);
  2837.     KMDTrace("TT", 5, "Kernel op #%d\taddr: 0x%06x\n", theOpNumber, theAddr);
  2838.     Map_Insert(KernelReturnOpNumberMap, theOpNumber, theAddr);
  2839.   Map_Next;
  2840.  
  2841.   LocationDeamonRunning = FALSE;
  2842. #define INITIALLISTCOUNT     20
  2843.   shoutList           = DynCreate(INITIALLISTCOUNT);
  2844.   searchList          = DynCreate(INITIALLISTCOUNT);
  2845.   listlength          = INITIALLISTCOUNT * sizeof(LocateInfo);
  2846.   CreateArray((int **)&list, listlength);
  2847. }
  2848.  
  2849. /**********************************************************************/
  2850. /*      Snapshots                                                     */
  2851. /**********************************************************************/
  2852.  
  2853. /**********************************************************************/
  2854. /*      LOCLocateMap                                                  */
  2855. /**********************************************************************/
  2856.  
  2857. /*Snapshot*/
  2858. void LOCLocateMap(fOID)
  2859. int fOID;
  2860. {
  2861.   LocateReqPtr req;
  2862.   int theOID;
  2863.  
  2864.   KMDPrint("LocateMap dump for node #%d\n", GetLNN());
  2865.   if (Map_Count(LocateMap) == 0) {
  2866.     KMDPrint("No outstanding location requests.\n");
  2867.     return;
  2868.   }
  2869.   KMDPrint("OID \t\tLoc. hint\tStatus\n");
  2870.   Map_For(LocateMap, theOID, req)
  2871.     if (NonNULL(fOID) && req->theOID == fOID) continue;
  2872.     KMDPrint("0x%08x\t0x04x\t%s\n", req->theOID,
  2873.          req->status == Waiting ?        "Waiting for previous locate" :
  2874.          req->status == WaitingForCodeLoad ? "Located; being loaded" :
  2875.          req->status == Confirming ?     "Confirming location hint" :
  2876.          req->status == Shouting ?       "Broadcast in progress" :
  2877.          req->status == Searching ?      "Searching; waiting for replies":
  2878.          "BAD STATUS");
  2879.     if (req->waiting)
  2880.       KMDPrint("\t\t\t%s in %s\n",
  2881.            PPPOID(req->waiting->processOID), PPSSPlace(req->waiting));
  2882.   Map_Next
  2883. }
  2884.  
  2885.  
  2886.  
  2887. /**********************************************************************/
  2888. /* Snapshot subroutine */
  2889. /* Prints an object table entry.*/
  2890. void snapOD(entry)
  2891. ODP entry;
  2892. {
  2893.   /*    ODP        first, p; */
  2894.  
  2895.   KMDPrint("OD (#%06x)  OID: 0x%05x, ODTag: %s\n", entry, entry->G.ownOID,
  2896.        PPODTag(entry->G.tag));
  2897.  
  2898. /*
  2899.   KMDPrint("Location LNN %d,    %s %s  %s\n", (int) entry->G.ownLoc,
  2900.            entry->G.setUpDone ? "Fully instantiated" : "Being initialized",
  2901.            entry->G.IsResident ? "Is resident" : "Non-resident");
  2902.   first = entry->G.ARListHead;
  2903.   if (first != (ODP) NULL) {
  2904.     char    buf[1000], buf2[1000];
  2905.     (void) sprintf(buf, "Active frames: ");
  2906.     p = first;
  2907.     do {
  2908.       (void) sprintf(buf2, " 0x%01x", p->ownOID);
  2909.       (void) strcat(buf, buf2);
  2910.       p = getNextAR(p);
  2911.     } while (p != first);
  2912.     KMDPrint("%-.72s\n", buf);
  2913.   }
  2914. */
  2915. }
  2916.  
  2917. /* Snapshot to dump an OT entry or the entire OT (in hash order) */
  2918. void OTDump(fIndex)
  2919. int fIndex;
  2920. {
  2921.   register SSPtr ssp;
  2922.   register int index;
  2923.   time_t   theTime = time((time_t *) 0);
  2924.   char     buf[1000], buf2[1000];
  2925.  
  2926.   KMDPrint("Object Table dump node %d     %s\n", GetLNN(), ctime(&theTime));
  2927.   if (NonNULL(currentSSP)) {
  2928.     KMDPrint(    "Running    : 0x%04x\n", currentSSP->processOID);
  2929.   }    
  2930.   if (NonNULL(readyQ)) {
  2931.     (void) sprintf(buf, "Ready Queue: ");
  2932.     ssp = getRQLink(readyQ);
  2933.     do {
  2934.       (void) sprintf(buf2, " 0x%01x", ssp->processOID);
  2935.       (void) strcat(buf, buf2);
  2936.       ssp = getRQLink(ssp);
  2937.     } while (ssp != readyQ);
  2938.     KMDPrint("%-.70s\n", buf);
  2939.   } else KMDPrint("Ready queue empty\n");
  2940.   if (fIndex == 0) {
  2941.     /* Full object table dump */
  2942.     for (index = 0; index < OTSize; index++) {
  2943.       if (OT[index]) snapOD(OT[index]);
  2944.     }
  2945.   } else KMDPrint("Index out of range.\n");
  2946. }
  2947.  
  2948.  
  2949.  
  2950. /*
  2951.  * snapData
  2952.  *
  2953.  * Prints a data area or OD.  Called from snapshot operations.
  2954.  */
  2955. void snapData(fEntry)
  2956. ODP fEntry;
  2957. {
  2958.   KMDPrint("ODBasicTag : %s\n", PPODTag(fEntry->G.tag));
  2959.  
  2960. #ifdef OBSOLETE
  2961.   KMDPrint("ODBasicTag : %s %s%s%s%s%s%s%s%s%s%s%c%c%s%s%s%s\n",
  2962.        BasicTagName[(int) fEntry->G.tag.tag],
  2963.        (fEntry->G.tag.global ? "Global " : ""),
  2964.        (fEntry->G.tag.replicated ? "Repl " : ""),
  2965.        (fEntry->G.tag.frozen ? "Frozen " : ""),
  2966.        (fEntry->G.tag.isResident ? "Resident " : "Remote "),
  2967.        (fEntry->G.tag.setUpDone ? "" : "Init "),
  2968.        (fEntry->G.tag.isFixed ? "Fixed " : ""),
  2969.        (fEntry->G.tag.inTransit ? "migrating " : ""),
  2970.        (fEntry->G.tag.allInstancesAreLocal ? "allLocal ": ""),
  2971.        (fEntry->G.tag.hasNoPointer ? "No ptr " : ""),
  2972.        (fEntry->G.tag.gcFrozen ? "gcFz " : ""),
  2973.        (fEntry->G.tag.gcMark1 ? '1' : ' '),
  2974.        (fEntry->G.tag.gcMark2 ? '2' : ' '),
  2975.        (fEntry->G.tag.xref ? "externally referenced " : ""),
  2976.        (fEntry->G.tag.localgcMark1 ? "l1" : " "),
  2977.        (fEntry->G.tag.localgcMark2 ? "l2" : " "),
  2978.        (fEntry->G.tag.otherstuff == OBSCUREVALUE) ? "" : " ** TRASHED **");
  2979. #endif OBSOLETE
  2980.  
  2981.   switch (fEntry->G.tag.tag) {
  2982.  
  2983.   case GODTag: {
  2984.     register InvokeQueuePtr     q, head;
  2985.  
  2986.     KMDPrint("GOD %s @ 0x%04x dataPtr 0x%06x, code: %s\n",
  2987.          PPGOID(fEntry->G.ownOID),
  2988.          fEntry->G.ownLoc, fEntry->G.dataPtr, PPCOID(fEntry->G.myCodeOID));
  2989.     if (!fEntry->G.tag.isResident) break;
  2990.  
  2991.     /* Dump invoke queue list */
  2992.     head = &fEntry->G.ARListHead;
  2993.     for (q = head->next; q != head; q = q->next) {
  2994.       KMDPrint("\tAR (0x%06x)\tProcess %s\n",
  2995.            addOffset(q, sizeof(InvokeQueue) + LOFFSETFROMDYNAMICLINK),
  2996.            PPPOID(((SSPtr) (-(int)(q->mySSPtr)))->processOID));
  2997.     }
  2998.     break;
  2999.   }
  3000.  
  3001.   case LOTag:
  3002.   case GODataTag: {
  3003.     register TemplateEntryPtr   t;
  3004.     register int                i;
  3005.     register Bytes             *dataAddr;
  3006.     CodePtr                     cPtr;
  3007.     TemplatePtr                 theTemplate;
  3008.  
  3009.     cPtr = fEntry->L.myCodePtr;
  3010.     assert(NonNULL(cPtr));
  3011.     KMDPrint("Instance size: %d\t\tone of %s\n", cPtr->instanceSize,
  3012.          PPCodePtr(cPtr));
  3013.     if (!cPtr->ODATemplateOffset) break;
  3014.     theTemplate = (TemplatePtr) addOffset(cPtr, cPtr->ODATemplateOffset);
  3015.     KMDPrint("Number of template entries %d\n",
  3016.          theTemplate->B.numEntries);
  3017.  
  3018.     t = &theTemplate->entry[0];
  3019.     if (fEntry->L.tag.replicated) {
  3020.       dataAddr = (Bytes *) &fEntry->R.inlineData[0];
  3021.     } else dataAddr = (Bytes *) &fEntry->L.inlineData[0];
  3022.  
  3023.     /*KMDPrint("Data starts at 0x%05x\n", dataAddr);*/
  3024.     for (i = 0; i < theTemplate->B.numEntries; i++) {
  3025.  
  3026.       switch (t->TE.SS.Format) {
  3027. /*
  3028.       case ShortDynamicF:
  3029.         KMDPrint("\tShortDynamicF\t(%s), data = %d, code = %d\n", 
  3030.             BrandNames[(int)t->TE.SD.theBrand], t->TE.SD.dataOffset,
  3031.             t->TE.SD.codeOffset);
  3032.         KMDPrint("Fix me: no dynamics in data areas\n");
  3033.         break;
  3034.  
  3035.         case LongDynamicF: {
  3036.         LongDynamic    *ld;
  3037.         ld = (LongDynamic *) t;
  3038.         KMDPrint("\tLongDynamicF\t(%s), data = %d, code = %d\n", 
  3039.             BrandNames[(int)ld->theBrand], ld->dataOffset,
  3040.             ld->codeOffset);
  3041.         i++;
  3042.         KMDPrint("Fix me: no dynamics in data areas\n");
  3043.         break;
  3044.         }
  3045. */
  3046.       case ShortStaticF: {
  3047.     KMDPrint(
  3048.          "\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  3049.          BrandNames[(int)t->TE.SS.theBrand],
  3050.          t->TE.SS.paramInfo != 0 ? "isParam" : " ",
  3051.          t->TE.SS.count);
  3052.  
  3053.     switch (t->TE.SS.theBrand) {
  3054.  
  3055.     case DataBrand: {
  3056.       register int            j;
  3057.       for (j = 0; j < t->TE.SS.count; j+=sizeof(int)) {
  3058.         KMDPrint("%6d: Data:  %08x\n",
  3059.              (dataAddr + j) - (Bytes *) fEntry,
  3060.              * ((int *)(dataAddr + j)));
  3061.       }
  3062.       dataAddr += t->TE.SS.count;
  3063.       break;
  3064.     }
  3065.  
  3066.     case ODPBrand: {
  3067.       register int            j;
  3068.       for (j = 1; j <= t->TE.SS.count; j++) {
  3069.         KMDPrint("%6d: ODP (0x%05x)\n", 
  3070.              dataAddr - (Bytes *) fEntry,
  3071.              * ((int *) dataAddr));
  3072.       }
  3073.       dataAddr += sizeof(ODP) * t->TE.SS.count;
  3074.       break;
  3075.     }
  3076.  
  3077.     case AddrBrand:{
  3078.       assert(t->TE.SS.theBrand != AddrBrand);
  3079.       dataAddr += t->TE.SS.count * sizeof(dataAddr);
  3080.       break;
  3081.     }
  3082.  
  3083.     case VectorBrand: {
  3084.       register VectorAreaPtr  v;
  3085.       register int            count;
  3086.  
  3087.       v         = (VectorAreaPtr) dataAddr;
  3088.       dataAddr     = (Bytes *) &v->data[0];
  3089.       count     = v->count;
  3090.  
  3091.       KMDPrint("\t\tElementBrand = %s, count %d\n",
  3092.            BrandNames[(int)t->TE.SS.elementBrand], count);
  3093.  
  3094.       switch (t->TE.SS.elementBrand) {
  3095.  
  3096.       case DataBrand: {
  3097.         if (fEntry->L.myCodePtr->ownOID == (unsigned int) 0xff00008b) {
  3098.           /* A real hack but for debug only */
  3099.           /* It is a string */
  3100.           KMDPrint("\t\tString: %.*s\n", count, &v->data[0]);
  3101.         } else KMDPrint("\t\tVector is data.\n");
  3102.         break;
  3103.       }
  3104.  
  3105.       case ODPBrand: {
  3106.         register ODP       *ODPAddr = (ODP *) dataAddr;
  3107.         register int        j;
  3108.         for (j = 0; j < count / sizeof(ODP); j++) {
  3109.           KMDPrint("\t\t%6d: ODP (0x%05x)%s\n", 
  3110.                j, *ODPAddr,
  3111.                t->TE.SS.attachedFlag ? " Attached" : "");
  3112.           ODPAddr++;
  3113.         }
  3114.         break;
  3115.       }
  3116.  
  3117.       case AddrBrand:{
  3118.         assert(FALSE);
  3119.         abort();
  3120.       }
  3121.  
  3122.       case VariableBrand: {
  3123.         register int            j;
  3124.         register AVariablePtr   varPtr;
  3125.  
  3126.         for (j = 0; j < count / sizeof(AVariable); j++){
  3127.           varPtr = (AVariablePtr) dataAddr;
  3128.           if (IsNIL(varPtr->myAddr) ||
  3129.           IsNIL(varPtr->myAbConPtr)) {
  3130.           KMDPrint("\t\t%6d: Var (NIL, NIL)\n", j);
  3131.           dataAddr += sizeof(AVariable);
  3132.           continue;
  3133.         }
  3134.           KMDPrint("\t\t%6d: Var (0x%01x, 0x%01x), %s\n",
  3135.                j, varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
  3136.           dataAddr += sizeof(AVariable);
  3137.         }
  3138.         break;
  3139.       }
  3140.  
  3141.       default: {
  3142.         ErrMsg("Bad element brand %s, in vector -- compiler error\n",
  3143.            PPBrand(t->TE.SS.elementBrand));
  3144.         abort();
  3145.       }
  3146.       } /* switch on Vector element brand*/
  3147.  
  3148.       break;
  3149.     } /* case Vector Brand */
  3150.  
  3151.     case VariableBrand: {
  3152.       register int            j;
  3153.       register AVariablePtr   varPtr;
  3154.  
  3155.       for (j = 1; j <= t->TE.SS.count; j++){
  3156.         varPtr = (AVariablePtr) dataAddr;
  3157.         KMDPrint("%6d: Variable (0x%04x, 0x%04x), %s\n",
  3158.              dataAddr - (Bytes *)fEntry,
  3159.              varPtr->myAddr, varPtr->myAbConPtr,
  3160.              PPVar(varPtr));
  3161.         dataAddr += sizeof(AVariable);
  3162.       }
  3163.       break;
  3164.     }
  3165.  
  3166.     case MonitorBrand: {
  3167.       register MonitorLockPtr     mPtr;
  3168.       register SSPtr              p;
  3169.  
  3170.       mPtr = (MonitorLockPtr) dataAddr;
  3171.       KMDPrint("%6d: Monitor %s\n", dataAddr - (Bytes *) fEntry,
  3172.            mPtr->isLocked ? "Locked" : "Open");
  3173.       /* for the following assert search for comments re
  3174.        * MONITOROFFSETWITHINOBJECT
  3175.        */
  3176.       assert(MONITOROFFSETWITHINOBJECT == byteOffset(fEntry, dataAddr));
  3177.       if (NonNULL(mPtr->waiting)) {
  3178.         KMDPrint("\tAwaiting entry:\n");
  3179.         p = getRQLink(mPtr->waiting);
  3180.         do {
  3181.           KMDPrint("\t\t%s in %s\n", PPPOID(p->processOID),
  3182.                PPSSPlace(p));
  3183.           p = getRQLink(p);
  3184.         } while (p != mPtr->waiting);
  3185.       }
  3186.       dataAddr += sizeof(MonitorLock);
  3187.       break;
  3188.     }
  3189.  
  3190.     default: {
  3191.       KMDPrint("Bad brand %s\n", PPBrand(t->TE.SS.theBrand));
  3192.     }
  3193.  
  3194.     } /* end switch */
  3195.  
  3196.     t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
  3197.     break;
  3198.       }
  3199.  
  3200.       case RegisterF:
  3201.     KMDPrint("\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  3202.          BrandNames[(int)t->TE.R.theBrand], 
  3203.          t->TE.R.storedWhere == InRegister ? "InRegister"
  3204.          : "InSaveArea", t->TE.R.reg, t->TE.R.count);
  3205.     KMDPrint("Compiler Error (?): registers in data area ???\n");
  3206.     break;
  3207.  
  3208.       default:
  3209.     KMDPrint("Bad format %d\n", t->TE.SS.Format);
  3210.     assert(FALSE);
  3211.     break;
  3212.       }
  3213.     }
  3214.     break;
  3215.   }
  3216.  
  3217.   case SSODTag: {
  3218.     register SSODP          myODP;
  3219.     myODP = (SSODP) fEntry;
  3220.  
  3221.     KMDPrint("SSOD @ 0x%04x  OID: %s, process %s\n", myODP->ownLoc,
  3222.          PPOID(myODP->ownOID), PPPOID(myODP->processOID));
  3223.     break;
  3224.   }
  3225.  
  3226.   case SSTag: {
  3227.     CodePtr                 cPtr;
  3228.     register SSPtr          p;
  3229.     register SSAddr         sAddr;
  3230.     register SSAddr         l;
  3231.     RegisterSave            regs;
  3232.     CodeAddr                ip = 0;
  3233.     GODP                    b;
  3234.     GODataPtr               g;
  3235.     SSAddr                  sp;
  3236.     TemplatePtr             tPtr;
  3237.     TemplateEntryPtr        entry;
  3238.     AVariablePtr            aVar;
  3239.     DynamicLinkPtr          theLink;
  3240.     int                     i, tOffset, it, k, argumentCount, resultCount;
  3241.     IPMapPtr                templateMap;
  3242.  
  3243.     p = (SSPtr) fEntry;
  3244.  
  3245.     if (IsNULL(p)) {
  3246.       KMDPrint("** NIL stack segment **\n");
  3247.       break;
  3248.     }
  3249.  
  3250.     KMDPrint("STACK SEGMENT      \tProcess %s\n", PPPOID(p->processOID));
  3251.     KMDPrint("SSPtr 0x%05x\n", p);
  3252.     KMDPrint("Status:\t\t\t%s%s\n", PPSSRunStatus((int)p->status.rs),
  3253.          ((p->status.rs != SSNotInUse) && (mStoppedAtEntry(p))) ?
  3254.          " Stopped at Operation Entry" : "");
  3255.     KMDPrint("Segment Size: \t\t%4d\n", p->segmentSize);
  3256.     KMDPrint("Available: \t\t%4d\n", p->availStack);
  3257.     KMDPrint("sp limit  \t\t0x%06x   (stack top limit)\n", p->splimit);
  3258.     KMDPrint("sp        \t\t0x%06x   (stack top)\n", p->regs.sp);
  3259.     KMDPrint("bottom:   \t\t0x%06x   (highest address)\n", p->endOfSS);
  3260.  
  3261.     if (p->status.rs == SSNotInUse) {
  3262.       KMDPrint("Stack Segment is not in use; on Hot Standby queue\n");
  3263.       break;
  3264.     }
  3265.  
  3266.     sAddr = sp = p->regs.sp;
  3267.     if (!SSValidAddr(p, sp)) {
  3268.       KMDPrint("** Empty Stack **\n");
  3269.       break;
  3270.     } else {
  3271.       KMDPrint("Current sp:\t\t0x%06x   (current address)\n", sp);
  3272.     }
  3273.     KMDPrint("splimit:  \t\t0x%06x   (low address)\n", p->splimit);
  3274.  
  3275.     ip      = * (CodeAddr *) sp;
  3276.     l       = p->regs.l;
  3277.     theLink = mDynLinkPtrFromL(l);
  3278.     b       = p->regs.b;
  3279.     g       = p->regs.g;
  3280.     regs    = p->regs;
  3281.  
  3282.     while (NonNULL(l) && SSValidAddr(p, l)) {
  3283.       cPtr = g->myCodePtr;
  3284.       if (IsNULL(cPtr)) {
  3285.     KMDPrint("Bad code ptr for l = 0x%05x\n", l);
  3286.     break;
  3287.       }
  3288.  
  3289.       /* Print the current activation record */
  3290.       KMDPrint("\nActivation record at %s, line %s\n",
  3291.            PPCodePtr(cPtr), PPFindLineNo(cPtr, ip));
  3292.       KMDPrint("b = 0x%05x, g = 0x%05x, sp = 0x%05x, l = 0x%05x\n",
  3293.            b, g, sp, l);
  3294.       KMDPrint("ip offset: %d (0x%05x)\n", byteOffset(cPtr, ip),
  3295.            byteOffset(cPtr, ip));
  3296.       if (IsNULL(cPtr->templateMapOffset)) {
  3297.     KMDPrint("No template IPMap\n");
  3298.     break;
  3299.       }
  3300.       templateMap = (IPMapPtr) addOffset(cPtr, cPtr->templateMapOffset);
  3301.       tOffset = IPMapLookup(templateMap, byteOffset(cPtr, ip));
  3302.       if (IsNULL(tOffset)) {
  3303.     KMDPrint("No template for offset\n", byteOffset(cPtr, ip));
  3304.     break;
  3305.       }
  3306.       tPtr = (TemplatePtr) addOffset(cPtr, tOffset);
  3307.       KMDPrint("%d entr%s in template\n", tPtr->B.numEntries,
  3308.            mPLURALY(tPtr->B.numEntries));
  3309.  
  3310.       /* Traverse the template and find argument and result counts */
  3311.       entry = &tPtr->entry[0];
  3312.       argumentCount = resultCount = 0;
  3313.       for (k = 0; k < tPtr->B.numEntries; k++, entry++) {
  3314.     if ((entry->TE.SS.Format == ShortStaticF) &&
  3315.         (entry->TE.SS.paramInfo != IsNotParam)) {
  3316.       /* There are parameters */
  3317.       if (entry->TE.SS.paramInfo == IsArgument) {
  3318.         argumentCount += entry->TE.SS.count;
  3319.       } else resultCount += entry->TE.SS.count;
  3320.     } else {
  3321.       break;
  3322.     }
  3323.       }
  3324.  
  3325.       entry = &tPtr->entry[0];
  3326.       aVar =
  3327.     (AVariablePtr)
  3328.       addOffset(theLink+1,(argumentCount+resultCount) * sizeof(AVariable));
  3329.       /* aVar now points to the high addr of the parameters */
  3330.  
  3331.       for (k = 0; k < tPtr->B.numEntries; k++, entry++)
  3332.     if ((entry->TE.SS.Format == ShortStaticF) &&
  3333.         (entry->TE.SS.paramInfo != IsNotParam)) {
  3334.       /* There are parameters */
  3335.       KMDPrint("\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  3336.            PPBrand(entry->TE.SS.theBrand),
  3337.            PPParamInfo(entry->TE.SS.paramInfo), entry->TE.SS.count);
  3338.       KMDPrint("%d parameter%s\n", entry->TE.SS.count,
  3339.            mPLURAL(entry->TE.SS.count));
  3340.       for (i =  entry->TE.SS.count; i > 0 ; i--) {
  3341.         KMDPrint("%4d: Param #%d (0x%05x, 0x%05x), %s\n",
  3342.              byteOffset(l, aVar), i, aVar->myAbConPtr, aVar->myAddr,
  3343.              PPVar(aVar));
  3344.         aVar--;
  3345.       }
  3346.     } else break;
  3347.       if (IsNULL(theLink->l)) {
  3348.     KMDPrint("%4d: DynamicLink, old  l: 0x%05x  (bottom)\n",
  3349.          byteOffset(l, &theLink->l), theLink->l);
  3350.       } else {
  3351.     KMDPrint("%4d: DynamicLink, old  l: 0x%05x  (l+%d)\n",
  3352.          byteOffset(l, &theLink->l), theLink->l,
  3353.          byteOffset(l, theLink->l));
  3354.       }
  3355.       KMDPrint("%4d: DynamicLink, old  g: 0x%05x\n",
  3356.            byteOffset(l, &theLink->g), theLink->g);
  3357.       KMDPrint("%4d: DynamicLink, old  b: 0x%05x\n",
  3358.            byteOffset(l, &theLink->b), theLink->b);
  3359.       KMDPrint("%4d: DynamicLink, old ip: 0x%05x\n",
  3360.            byteOffset(l, &theLink->ip), theLink->ip);
  3361.       sAddr = (SSAddr) theLink;
  3362.       entry = &tPtr->entry[0];
  3363.  
  3364.       for (it = 0; it < tPtr->B.numEntries; it++) {
  3365.     if (entry->TE.SS.Format == RegisterF) {
  3366.       int             reg;
  3367.       register TemplateEntryPtr t = entry;
  3368.  
  3369.       KMDPrint("\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  3370.            BrandNames[(int)t->TE.R.theBrand], 
  3371.            t->TE.R.storedWhere==InRegister ? "InRegister":"InSaveArea",
  3372.            t->TE.R.reg, t->TE.R.count);
  3373.       if (t->TE.R.storedWhere == InSaveArea) {
  3374.         for (reg = t->TE.R.count - 1 ; reg >= 0; reg--) {
  3375.           /* Registers are stored low number, low addr */
  3376.           sAddr--; /* Since we are going backwards */
  3377.           KMDPrint("%4d: Saved Register r%d:\t0x%08x\n",
  3378.                byteOffset(l, sAddr), t->TE.R.reg+reg, *sAddr);
  3379.         }
  3380.       } else {
  3381.         for (reg = 0; reg < t->TE.R.count; reg++) {
  3382.           switch (t->TE.R.theBrand) {
  3383.           case DataBrand: {
  3384.         KMDPrint("\tIn r%d: Data:\t0x%08x\n",
  3385.              t->TE.R.reg+reg,mGetSavedReg(®s, t->TE.R.reg+reg));
  3386.         break;
  3387.           }
  3388.           case ODPBrand: {
  3389.         ODP        regValue;
  3390.         regValue = (ODP) mGetSavedReg(®s, t->TE.R.reg+reg);
  3391.         KMDPrint("\tIn r%d: ODP:\t0x%08x\t%s\n",
  3392.              t->TE.R.reg+reg, regValue, PPODP(regValue));
  3393.         break;
  3394.           }
  3395.           case VariableBrand: {
  3396.         AVariable       theVar;
  3397.         theVar.myAddr = (DataAddr)
  3398.           mGetSavedReg(®s, t->TE.R.reg+reg);
  3399.         theVar.myAbConPtr = (AbConPtr)
  3400.           mGetSavedReg(®s, t->TE.R.reg+reg+1);
  3401.         KMDPrint("\tIn r%d-%d: Var: %s\n",
  3402.              t->TE.R.reg+reg, t->TE.R.reg+reg+1, PPVar(&theVar));
  3403.         reg++; /* Since vars take 2 registers */
  3404.         break;
  3405.           }
  3406.           default: {
  3407.         ErrMsg("Brand %d not allowed in snapData\n", t->TE.R.theBrand);
  3408.         KMDPrint("Brand %d not allowed insnapData\n",t->TE.R.theBrand);
  3409.           }
  3410.  
  3411.           } /* end switch (t->TE.R.theBrand) */
  3412.         }
  3413.       }
  3414.       t = (TemplateEntryPtr) addOffset(t, sizeof(t->TE.R));
  3415.       entry = t;
  3416.  
  3417.       continue;
  3418.     }
  3419.  
  3420.     assert(entry->TE.SS.Format == ShortStaticF);
  3421.     if (entry->TE.SS.paramInfo != IsNotParam) {
  3422.       KMDTrace("FixMe", 5,
  3423.            "Portability: entry++ might not add right amount\n");
  3424.       entry++;
  3425.       continue;
  3426.     }
  3427.  
  3428.     KMDPrint("\tShortStaticF\t(%s)\tcount =%4d\n", 
  3429.          BrandNames[(int)entry->TE.SS.theBrand], entry->TE.SS.count);
  3430.  
  3431.     switch (entry->TE.SS.theBrand) {
  3432.     case DataBrand: {
  3433.       register int j;
  3434.       int intCount;
  3435.       assert (entry->TE.SS.count % sizeof(int) == 0);
  3436.       intCount = entry->TE.SS.count/sizeof(int);
  3437.       for (j = intCount; j > 0; j--) {
  3438.         sAddr--;
  3439.         KMDPrint("%4d: Data:  \t0x%08x\n", byteOffset(l, sAddr), *sAddr);
  3440.       }    
  3441.       break;
  3442.     }
  3443.  
  3444.     case ODPBrand: {
  3445.       register int            j;
  3446.       register ODP           *theODPPtr;
  3447.       theODPPtr = (ODP *) sAddr;
  3448.       for (j = 1; j <= entry->TE.SS.count; j++) {
  3449.         theODPPtr--;
  3450.         KMDPrint("%4d: ODP \t(0x%05x)\n", 
  3451.              byteOffset(l, theODPPtr), * ((int *) theODPPtr));
  3452.       }
  3453.       sAddr = (SSAddr) theODPPtr;
  3454.       break;
  3455.     }
  3456.  
  3457.     case AddrBrand:{
  3458.       sAddr -= entry->TE.SS.count;
  3459.       KMDPrint("%4d: Address \t(0x%05x) count %d\n",
  3460.            *(int *)sAddr, entry->TE.SS.count);
  3461.       break;
  3462.     }
  3463.  
  3464.     case VectorBrand: {
  3465.       KMDPrint("Vector (in SS ??) ElementBrand = %s\n",
  3466.            BrandNames[(int)entry->TE.SS.elementBrand]);
  3467.       assert(entry->TE.SS.theBrand != VectorBrand);
  3468.       break;
  3469.     }
  3470.  
  3471.     case VariableBrand: {
  3472.       register int j;
  3473.       register AVariablePtr   varPtr;
  3474.  
  3475.       for (j = 1; j <= entry->TE.SS.count; j++){
  3476.         sAddr = (SSAddr) addOffset(sAddr, -sizeof(AVariable));
  3477.         varPtr = (AVariablePtr) sAddr;                    
  3478.         KMDPrint("%4d: Variable\t(0x%04x, 0x%04x), %s\n",
  3479.              byteOffset(l, sAddr),
  3480.              varPtr->myAddr, varPtr->myAbConPtr,
  3481.              PPVar(varPtr));
  3482.       }
  3483.       break;
  3484.     }
  3485.  
  3486.     case MonitorBrand: {
  3487.       register MonitorLockPtr     mPtr;
  3488.       register SSPtr              ptr;
  3489.  
  3490.       sAddr = (SSAddr) addOffset(sAddr, sizeof(MonitorLock));
  3491.       mPtr = (MonitorLockPtr) sAddr;
  3492.       KMDPrint("    *** Monitor in Activation record !!??\n");
  3493.       KMDPrint("%4d: Monitor %s\n",
  3494.            byteOffset(l, sAddr), mPtr->isLocked ? "Locked" : "Open");
  3495.       if (NonNULL(mPtr->waiting)) {
  3496.         KMDPrint("            Awaiting entry:\n");
  3497.         ptr = getRQLink(mPtr->waiting);
  3498.         do {
  3499.           KMDPrint("              0x%04x\n", ptr->processOID);
  3500.           ptr = getRQLink(ptr);
  3501.         } while (ptr != mPtr->waiting);
  3502.       }
  3503.       break;
  3504.     }
  3505.  
  3506.     case InvokeQueueBrand: {
  3507.       sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
  3508.       if (*(sAddr+2) < 0) {
  3509.         KMDPrint("%4d: InvokeQueue\t(0x%05x, 0x%05x) *(0x%05x)\n",
  3510.              byteOffset(l, sAddr), *sAddr,  *(sAddr+1), -(*(sAddr+2)));
  3511.       } else {
  3512.         KMDPrint("%4d: InvokeQueue\t(0x%05x, 0x%05x)  (0x%05x)\n",
  3513.              byteOffset(l, sAddr), *sAddr,  *(sAddr+1), (*(sAddr+2)));
  3514.       }
  3515.       break;
  3516.     }
  3517.  
  3518.     default: {
  3519.       KMDPrint("Bad brand %s in snapData\n",
  3520.            PPBrand(entry->TE.SS.theBrand));
  3521.       assert(FALSE);
  3522.     }
  3523.  
  3524.     } /* end switch (entry->TE.SS.theBrand) */
  3525.  
  3526.     entry = (TemplateEntryPtr) addOffset(entry, sizeof(ShortStatic));
  3527.       }
  3528.  
  3529.       /* The rest is assumed to be variables */
  3530.       {
  3531.     register AVariablePtr   varPtr;
  3532.     varPtr = (AVariablePtr) sAddr;
  3533.     varPtr --;
  3534.     while (SSValidAddr(p, (SSAddr) varPtr) && ( (SSAddr) varPtr >= sp)) {
  3535.       KMDPrint("%4d: Variable (0x%04x, 0x%04x), %s\n",
  3536.            byteOffset(l, varPtr),
  3537.            varPtr->myAddr, varPtr->myAbConPtr, PPVar(varPtr));
  3538.       varPtr--;
  3539.     }
  3540.       }
  3541.       KMDPrint("\n********** End of activation record *********\n");
  3542.  
  3543.       /* Now move on to the next activation record */
  3544.  
  3545.       /* Restore registers from register save area */
  3546.  
  3547.       entry       = &tPtr->entry[0];
  3548.       sAddr       = (SSAddr) theLink;
  3549.       for (i = 0; i < tPtr->B.numEntries; i++) {
  3550.  
  3551.     switch (entry->TE.SS.Format) {
  3552.  
  3553.     case ShortStaticF: {
  3554.       KMDPrint("\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  3555.            BrandNames[(int)entry->TE.SS.theBrand],
  3556.            entry->TE.SS.paramInfo != 0 ? "isParam" : " ",
  3557.            entry->TE.SS.count);
  3558.  
  3559.       switch (entry->TE.SS.theBrand) {
  3560.  
  3561.       case DataBrand: {
  3562.         sAddr = (SSAddr) addOffset(sAddr, -entry->TE.SS.count);
  3563.         break;
  3564.       }
  3565.  
  3566.       case ODPBrand: {
  3567.         sAddr = (SSAddr) addOffset(sAddr, -sizeof(ODP)*entry->TE.SS.count);
  3568.         break;
  3569.       }
  3570.  
  3571.       case AddrBrand:{
  3572.         assert(entry->TE.SS.theBrand != AddrBrand);
  3573.         break;
  3574.       }
  3575.  
  3576.       case VectorBrand: {
  3577.         break;
  3578.       } /* case Vector Brand */
  3579.  
  3580.       case VariableBrand: {
  3581.         sAddr = (SSAddr)
  3582.           addOffset(sAddr, -sizeof(AVariable)*entry->TE.SS.count);
  3583.         break;
  3584.       }
  3585.  
  3586.       case MonitorBrand: {
  3587.         sAddr = (SSAddr) addOffset(sAddr, -sizeof(MonitorLock));
  3588.         break;
  3589.       }
  3590.  
  3591.       case InvokeQueueBrand: {
  3592.         sAddr = (SSAddr) addOffset(sAddr, -sizeof(InvokeQueue));
  3593.         break;
  3594.       }
  3595.  
  3596.       default: {
  3597.         ErrMsg("Bad brand %s in snapData (ARend)\n",
  3598.            PPBrand(entry->TE.SS.theBrand));
  3599.         break;
  3600.       }
  3601.  
  3602.       } /* end switch (entry->TE.SS.theBrand) */
  3603.  
  3604.       entry = (TemplateEntryPtr) addOffset(entry, sizeof(ShortStatic));
  3605.       break;
  3606.     }
  3607.  
  3608.     case RegisterF: {
  3609.       KMDPrint("\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  3610.            BrandNames[(int)entry->TE.R.theBrand], 
  3611.            entry->TE.R.storedWhere == InRegister ? "InRegister"
  3612.            : "InSaveArea", entry->TE.R.reg, entry->TE.R.count);
  3613.       if (entry->TE.R.storedWhere == InSaveArea) {
  3614.         for (k = entry->TE.R.count - 1 ; k >= 0; k--) {
  3615.           /* Registers are stored low number, low addr */
  3616.           sAddr--; /* Since we are going backwards, do -- first */
  3617.           KMDPrint("Restoring r%d, was 0x%02x, now 0x%02x\n", 
  3618.                entry->TE.R.reg+k,
  3619.                mGetSavedReg(®s, entry->TE.R.reg+k),
  3620.                *sAddr);
  3621.           mSetSavedReg(®s, entry->TE.R.reg+k, *sAddr);
  3622.         }
  3623.       }
  3624.       entry = (TemplateEntryPtr) addOffset(entry, sizeof(entry->TE.R));
  3625.       break;
  3626.     } /* case RegisterF */
  3627.  
  3628.     default: {
  3629.       KMDPrint("Bad format 0x%02x\n", entry->TE.SS.Format);
  3630.       abort();
  3631.       break;
  3632.     } /* default action */
  3633.  
  3634.     } /* switch on entry->TE.SS.Format */
  3635.       } /* for (i = 0; ...) */
  3636.  
  3637.       ip      = theLink->ip;
  3638.       b       = theLink->b;
  3639.       g       = theLink->g;
  3640.       l       = theLink->l;
  3641.       sp      = (SSAddr) (theLink+1);
  3642.       theLink = mDynLinkPtrFromL(l);
  3643.     } /* while there are more ARs */
  3644.  
  3645.     /* Now print the Requests */
  3646.     break;
  3647.   }
  3648.  
  3649.     case CodeODTag: {
  3650.     register CodePtr        cPtr;
  3651.     StringPtr     cName;
  3652.     cPtr = fEntry->C.dataPtr;
  3653.     if (IsNULL(cPtr)) {
  3654.         KMDPrint("Non-resident Code OID %s\n", PPCOID(fEntry->C.ownOID));
  3655.         break;
  3656.     }
  3657.     /* Note, the following should use PPCodePtr */
  3658.     cName = (StringPtr) addOffset(cPtr, cPtr->codeNameOffset);
  3659.     KMDPrint("Resident Code (0x%06x) OID 0x%04x\t\t%.*s\n", cPtr,
  3660.         cPtr->ownOID, cName->sizeInBytes, &cName->data[0]);
  3661.     break;
  3662.     }
  3663.     
  3664.     case AbConTag: {
  3665.     register AbConPtr       ab;
  3666.     
  3667.     ab = (AbConPtr) fEntry;
  3668.     KMDPrint("AbCon (%s, %s)\n", PPCOID(ab->ATOID), PPCOID(ab->CodeOID));
  3669.     if (NonNIL(ab->restrictOID)) {
  3670.         KMDPrint("Restricted to %s\n", PPCOID(ab->restrictOID));
  3671.     } else {
  3672.         KMDPrint("Not restricted\n");
  3673.     }
  3674.     
  3675.     break;
  3676.     }
  3677.     
  3678.     case CodeTag: {
  3679.     register CodePtr        c;
  3680.     c = (CodePtr) fEntry;
  3681.     KMDPrint("Code data area:  %s\n", PPCodePtr(c));
  3682.     break;
  3683.     }
  3684.  
  3685.     case CondTag: {
  3686.         register CondODP        cd;
  3687.         register SSPtr          p;
  3688.     
  3689.         cd = (CondODP) fEntry;
  3690.     KMDPrint("Condition  (0x%06x) tied to lock at 0x%05x\n", cd,
  3691.         cd->theLock);
  3692.     KMDPrint("OwnOID: %s\n", PPOID(cd->ownOID));
  3693.         if (NonNULL(cd->waiting)) {
  3694.         p       = cd->waiting;
  3695.         do {
  3696.                 p = getRQLink(cd->waiting);
  3697.         KMDPrint("\tWaiting process \t%s\n", PPPOID(p->processOID));
  3698.         } while (p != cd->waiting);
  3699.     }
  3700.     break;
  3701.     }
  3702.     
  3703.     case DotoTag: {
  3704.     KMDPrint("DotoFile contains:\n");
  3705.     snapData((ODP)
  3706.         dotoCodePtr((DotoFilePtr) addOffset(fEntry, sizeof(ODTag))));
  3707.     break;
  3708.     }
  3709.     
  3710.     default:
  3711.     KMDPrint("Unknown Tag %s\n", PPODTag(fEntry->G.tag));
  3712.     break;
  3713.     }
  3714. }
  3715.  
  3716. /* Snapshot */
  3717. void OTDataDump(fIndex)
  3718. int        fIndex;
  3719. /* Snapshot to dump an OT entry or the entire OT (in hash order) */
  3720. {
  3721.     register int index;
  3722.     time_t   theTime = time((time_t *) 0);
  3723.  
  3724.     KMDPrint("Object Table dump on node %d     %s\n", GetLNN(),
  3725.     ctime(&theTime));
  3726.  
  3727.     ps();
  3728.  
  3729.     if (IsNULL(fIndex)) {
  3730.     for (index = 0; index < OTSize; index++) {
  3731.         if (NonNULL(OT[index])) snapData(OT[index]);
  3732.     }
  3733.     } else {
  3734.     /* Dump the given OID */
  3735.     ODP     theODP = OTLookup((OID) fIndex);
  3736.     if (NonNULL(theODP)) {
  3737.         snapData(theODP);
  3738.     } else {
  3739.         KMDPrint("OID 0x%04x is not in the Object Table\n", fIndex);
  3740.     }
  3741.     }
  3742. }
  3743. /*
  3744.  * snapCTData
  3745.  *
  3746.  * Prints CTs that the kernel has.  Called from snapshot operations.
  3747.  */
  3748. void snapCTData(fEntry)
  3749. ODP fEntry;
  3750. {
  3751.   switch (fEntry->G.tag.tag) {
  3752.  
  3753.   case GODTag:
  3754.   case LOTag:
  3755.   case GODataTag: 
  3756.   case SSODTag:
  3757.   case SSTag: {
  3758.         break;
  3759.     };
  3760.  
  3761.   case CodeODTag: {
  3762.     register CodePtr        cPtr;
  3763.     cPtr = fEntry->C.dataPtr;
  3764.     if (IsNULL(cPtr)) {
  3765.         KMDPrint("Non-resident Code OID %s\n", PPCOID(fEntry->C.ownOID));
  3766.         break;
  3767.     }
  3768.     KMDPrint("Resident Code OID %s\t\t%.*s\n", PPCOID(cPtr->ownOID));
  3769.     break;
  3770.     }
  3771.     
  3772.     case AbConTag: {
  3773.     register AbConPtr       ab;
  3774.     
  3775.     ab = (AbConPtr) fEntry;
  3776.     KMDPrint("AT Code OID\t%s\nCT Code OID\t%s\n", PPCOID(ab->ATOID),
  3777.       PPCOID(ab->CodeOID));
  3778.     if (NonNIL(ab->restrictOID)) {
  3779.         KMDPrint("Restrict Code OID\t%s\n", PPCOID(ab->restrictOID));
  3780.     };
  3781.     
  3782.     break;
  3783.     }
  3784.     
  3785.     case CodeTag: {
  3786.     break;
  3787.     }
  3788.  
  3789.     case CondTag: {
  3790.     break;
  3791.     }
  3792.     
  3793.     case DotoTag: {
  3794.     snapCTData((ODP)
  3795.         dotoCodePtr((DotoFilePtr) addOffset(fEntry, sizeof(ODTag))));
  3796.     break;
  3797.     }
  3798.     
  3799.     default:
  3800.     KMDPrint("Unknown Tag %s\n", PPODTag(fEntry->G.tag));
  3801.     break;
  3802.     }
  3803. }
  3804.  
  3805. /**********************************************************************/
  3806. /*      Declarations for EmDataDump and EmDatumDump                   */
  3807. /**********************************************************************/
  3808. int     count[(int) LastODBasicTag];
  3809. double  sumOfSize[(int) LastODBasicTag];
  3810.  
  3811. /**********************************************************************/
  3812. /*      EmDatumDump                                                   */
  3813. /**********************************************************************/
  3814.  
  3815. void EmDatumDump(fAddr, fSize)
  3816. ODP             fAddr;
  3817. unsigned int    fSize;
  3818. {
  3819.     extern int KMDSnapSock;
  3820.     /*
  3821.      * The following is a hack to make the kernel get done faster when the
  3822.      * user kills the dump prematurely.  Performance optimizaiton: It can
  3823.      * safely be removed.
  3824.      */
  3825.     if (KMDSnapSock == NULL) return;
  3826.  
  3827.     KMDPrint("\n**** 0x%06x **** size: %4d bytes ********************\n",
  3828.     fAddr, fSize);
  3829.     count[(int) fAddr->G.tag.tag]++;
  3830.     sumOfSize[(int) fAddr->G.tag.tag] += (double) fSize;
  3831.     snapData(fAddr);
  3832. }
  3833.  
  3834. /**********************************************************************/
  3835. /*      EmCTDatumDump                                                 */
  3836. /**********************************************************************/
  3837.  
  3838. void EmCTDatumDump(fAddr, fSize)
  3839. ODP             fAddr;
  3840. unsigned int    fSize;
  3841. {
  3842.     extern int KMDSnapSock;
  3843.     /*
  3844.      * The following is a hack to make the kernel get done faster when the
  3845.      * user kills the dump prematurely.  Performance optimizaiton: It can
  3846.      * safely be removed.
  3847.      */
  3848.     if (KMDSnapSock == NULL) return;
  3849.  
  3850.     snapCTData(fAddr);
  3851. }
  3852.  
  3853. /**********************************************************************/
  3854. /*      EmDataDump                                                    */
  3855. /**********************************************************************/
  3856. /* Snapshot */
  3857. void EmDataDump()
  3858. /* Dumps the Emerald allocated data areas */
  3859. {
  3860.     time_t  theTime = time((time_t *) 0);
  3861.     int     i;
  3862.     double  sum = 0.0;
  3863.     int     total = 0;
  3864.     
  3865.     for (i = 0; i < (int) LastODBasicTag; i++) {
  3866.     count[i] = 0;
  3867.     sumOfSize[i] = 0.0;
  3868.     }
  3869.     
  3870.     KMDPrint("Emerald data area dump on node #%d at %s", GetLNN(),
  3871.     ctime(&theTime));
  3872.     EmallocForEach(EmDatumDump);
  3873.     KMDPrint("******** Emerald data area stats ********\n");
  3874.     KMDPrint("Tag\t\tCount\tSumOfSize\tAvg.size\n");
  3875.     for (i = 0; i < (int) LastODBasicTag; i++) {
  3876.     if (count[i] == 0) continue;
  3877.     KMDPrint("%-12.12s\t%4d\t%10.0f\t%10.2f\n",
  3878.         PPODBasicTag((ODBasicTag) i), count[i], sumOfSize[i],
  3879.         sumOfSize[i]/((count[i]>0) ? (double) count[i] : 1.0));
  3880.     total += count[i];
  3881.     sum += sumOfSize[i];
  3882.     }
  3883.     if (total)
  3884.     KMDPrint("Total\t\t%4d\t%10.0f\t%10.2f\n", total, sum, sum/total);
  3885.     KMDPrint("******** Emerald data area dump done ********\n");
  3886. }
  3887.  
  3888. /**********************************************************************/
  3889. /*      EmCTRefDump                                                   */
  3890. /**********************************************************************/
  3891. /* Snapshot */
  3892. void EmCTRefDump()
  3893. /* Dumps the Emerald allocated data areas */
  3894. {
  3895.     time_t  theTime = time((time_t *) 0);
  3896.     int     i;
  3897.     KMDPrint("Emerald CT dump on node #%d at %s", GetLNN(),
  3898.     ctime(&theTime));
  3899.      EmallocForEach(EmCTDatumDump);
  3900. }
  3901.  
  3902. /**********************************************************************/
  3903. /*      Template                                                      */
  3904. /**********************************************************************/
  3905. TemplatePtr FindTemplate(fCodePtr, fIP)
  3906. CodePtr         fCodePtr;
  3907. Offset          fIP;
  3908. {
  3909.     IPMapPtr        templateMap;
  3910.     Offset          tOffset;
  3911.     
  3912.     assert(fCodePtr->templateMapOffset != 0);
  3913.     templateMap = (IPMapPtr) addOffset(fCodePtr, fCodePtr->templateMapOffset);
  3914.     tOffset = IPMapLookup(templateMap, byteOffset(fCodePtr, fIP));
  3915.     assert(tOffset != (Offset) 0);
  3916.     return (TemplatePtr) addOffset(fCodePtr, tOffset);
  3917. }
  3918.  
  3919. int FindVectorSize(fVectorPtr)
  3920. VectorPtr        fVectorPtr;
  3921. /* Find the size of a vector */
  3922. {
  3923.     CodePtr            cp;
  3924.     TemplatePtr            template;
  3925.     register TemplateEntryPtr    t;
  3926.     register int        i;
  3927.     Bytes            *dataAddr;
  3928.     
  3929.     /* Must dig size out of template */
  3930.     cp            = fVectorPtr->myCodePtr;
  3931.     template         = (TemplatePtr) addOffset(cp, cp->ODATemplateOffset);
  3932.     t            = (TemplateEntryPtr) &template->entry[0];
  3933.     if (cp->instanceTag.replicated) {
  3934.     dataAddr = (Bytes *) &(((ODP) fVectorPtr)->R.inlineData[0]);
  3935.     } else {
  3936.     dataAddr = (Bytes *) &(((ODP) fVectorPtr) ->L.inlineData[0]);
  3937.     }
  3938.     
  3939.     for (i = template->B.numEntries; i > 0; i--) {
  3940.     switch (t->TE.SS.Format) {
  3941.     case ShortStaticF: {
  3942.         KMDTrace("Vector", 5,
  3943.         "\tShortStaticF\t(%s) %s\tcount =%4d\n", 
  3944.         PPBrand(t->TE.SS.theBrand),
  3945.         t->TE.SS.paramInfo != 0 ? "isParam" : " ",
  3946.         t->TE.SS.count);
  3947.  
  3948.         switch (t->TE.SS.theBrand) {
  3949.  
  3950.         case DataBrand: {
  3951.         register int            j;
  3952.         for (j = 0; j < t->TE.SS.count; j+=sizeof(int)) {
  3953.             KMDTrace("Vector", 5, "%6d: Data:  %08x\n",
  3954.             (dataAddr + j) - (Bytes *) fVectorPtr,
  3955.             * ((int *)(dataAddr + j)));
  3956.         }
  3957.         /* HACK: compiler generates a count of one instead of four */
  3958.         dataAddr += (t->TE.SS.count == 1 ? 4 : t->TE.SS.count);
  3959.         break;
  3960.         }
  3961.         
  3962.         case ODPBrand: {
  3963.         register int            j;
  3964.         for (j = 1; j <= t->TE.SS.count; j++) {
  3965.             KMDTrace("Vector", 5, "%6d: ODP (0x%05x)\n", 
  3966.             dataAddr - (Bytes *) fVectorPtr,
  3967.             * ((int *) dataAddr));
  3968.         }
  3969.         dataAddr += sizeof(ODP) * t->TE.SS.count;
  3970.         break;
  3971.         }
  3972.         
  3973.         case AddrBrand:{
  3974.         assert(t->TE.SS.theBrand != AddrBrand);
  3975.         dataAddr += t->TE.SS.count * sizeof(dataAddr);
  3976.         break;
  3977.         }
  3978.  
  3979.         case VectorBrand: {
  3980.         register VectorAreaPtr  v;
  3981.         register int            lcount;
  3982.  
  3983.         v         = (VectorAreaPtr) dataAddr;
  3984.         dataAddr     = (Bytes *) &v->data[0];
  3985.         lcount         = v->count;
  3986.         
  3987.         KMDTrace("Vector", 5, 
  3988.             "\t\tElementBrand = %s, count %d\n",
  3989.             BrandNames[(int)t->TE.SS.elementBrand], lcount);
  3990.         KMDTrace("Vector", 5, "\t\tVector type %s\n",
  3991.             PPCOID(fVectorPtr->myCodePtr->ownOID));
  3992.  
  3993.         switch (t->TE.SS.elementBrand) {
  3994.  
  3995.         case DataBrand: {
  3996.             if (fVectorPtr->myCodePtr->ownOID
  3997.             == (unsigned int) 0xff00008b) {
  3998.             /* A real hack but for debug only */
  3999.             /* It is a string */
  4000.             KMDTrace("Vector", 5, "\t\tString: %.*s\n", lcount,
  4001.                 &v->data[0]);
  4002.             } else KMDTrace("Vector", 5, "\t\tVector is data.\n");
  4003.             dataAddr += lcount;
  4004.             break;
  4005.         }
  4006.  
  4007.         case ODPBrand: {
  4008.             register ODP       *ODPAddr = (ODP *) dataAddr;
  4009.             register int        j;
  4010.             for (j = 0; j < lcount / sizeof(ODP); j++) {
  4011.             KMDTrace("Vector", 5, 
  4012.                 "\t\t%6d: %s %s\n",
  4013.                 j, PPODP(*ODPAddr),
  4014.                 t->TE.SS.attachedFlag ? " Attached" : "");
  4015.             ODPAddr++;
  4016.             }
  4017.             dataAddr += lcount;
  4018.             break;
  4019.         }
  4020.         
  4021.         case VariableBrand: {
  4022.             register int            j;
  4023.             register AVariablePtr   varPtr;
  4024.  
  4025.             for (j = 0; j < lcount / sizeof(AVariable); j++){
  4026.             varPtr = (AVariablePtr) dataAddr;
  4027.             if (IsNIL(varPtr->myAddr) ||
  4028.                 IsNIL(varPtr->myAbConPtr))
  4029.             {
  4030.                 KMDTrace("Vector", 5, "\t\t%6d: Var (NIL, NIL)\n", j);
  4031.                 continue;
  4032.             }
  4033.             KMDTrace("Vector", 5, 
  4034.                 "\t\t%6d: Var (0x%01x, 0x%01x), %s\n", j,
  4035.                 varPtr->myAddr, varPtr->myAbConPtr,
  4036.                 PPVar(varPtr));
  4037.             }
  4038.             dataAddr += lcount;
  4039.             break;
  4040.         }
  4041.  
  4042.         default: {
  4043.             ErrMsg(
  4044.             "Bad element brand %s, in vector -- compiler error\n",
  4045.             PPBrand(t->TE.SS.elementBrand));
  4046.             abort();
  4047.         }
  4048.  
  4049.         } /* switch on Vector element brand*/
  4050.         
  4051.         break;
  4052.         } /* case Vector Brand */
  4053.         
  4054.         case VariableBrand: {
  4055.         register int            j;
  4056.         register AVariablePtr   varPtr;
  4057.         
  4058.         for (j = 1; j <= t->TE.SS.count; j++){
  4059.             varPtr = (AVariablePtr) dataAddr;
  4060.             KMDTrace("Vector", 5, "%6d: Variable (0x%04x, 0x%04x), %s\n",
  4061.             dataAddr - (Bytes *)fVectorPtr,
  4062.             varPtr->myAddr, varPtr->myAbConPtr,
  4063.             PPVar(varPtr));
  4064.             dataAddr += sizeof(AVariable);
  4065.         }
  4066.         break;
  4067.         }
  4068.         
  4069.         case MonitorBrand: {
  4070.         register MonitorLockPtr     mPtr;
  4071.         register SSPtr              p;
  4072.         
  4073.         mPtr = (MonitorLockPtr) dataAddr;
  4074.         KMDTrace("Vector", 5, "%6d: Monitor %s\n",
  4075.             dataAddr - (Bytes *) fVectorPtr,
  4076.             mPtr->isLocked ? "Locked" : "Open");
  4077.         /* for the following assert search for comments re
  4078.          * MONITOROFFSETWITHINOBJECT
  4079.          */
  4080.         assert(MONITOROFFSETWITHINOBJECT == byteOffset(fVectorPtr, dataAddr));
  4081.         if (NonNULL(mPtr->waiting)) {
  4082.             KMDTrace("Vector", 5, "\tAwaiting entry:\n");
  4083.             p = getRQLink(mPtr->waiting);
  4084.             do {
  4085.             KMDTrace("Vector", 5, "\t\t%s in %s\n",
  4086.                 PPPOID(p->processOID), PPSSPlace(p));
  4087.             p = getRQLink(p);
  4088.             } while (p != mPtr->waiting);
  4089.         }
  4090.         dataAddr += sizeof(MonitorLock);
  4091.         break;
  4092.         }
  4093.         
  4094.         default: {
  4095.         KMDTrace("Vector", 5, "Bad brand %s in FindVectorSize\n",
  4096.             PPBrand(t->TE.SS.theBrand));
  4097.         }
  4098.  
  4099.         } /* end switch */
  4100.  
  4101.         t = (TemplateEntryPtr) addOffset(t, sizeof(ShortStatic));
  4102.         break;
  4103.     }
  4104.  
  4105.     case RegisterF:
  4106.     KMDTrace("Vector", 5, "\tRegisterF\t(%s),\t%s, r%d, count %d\n",
  4107.         BrandNames[(int)t->TE.R.theBrand], 
  4108.         t->TE.R.storedWhere == InRegister ? "InRegister"
  4109.         : "InSaveArea", t->TE.R.reg, t->TE.R.count);
  4110.         KMDTrace("Vector", 5,
  4111.         "Compiler Error (?): registers in data area ???\n");
  4112.         break;
  4113.     
  4114.     default:
  4115.         ErrMsg("Bad format %d\n", t->TE.SS.Format);
  4116.         abort();
  4117.         break;
  4118.     }
  4119.     }
  4120.     i = (int) (byteOffset(fVectorPtr, dataAddr));
  4121.     KMDTrace("Vector", 4, "Size returned is %d\n", i);
  4122.     return i;
  4123. }
  4124.  
  4125. /* Copyright 1986 Eric Jul */
  4126.